2017-03-22 3 views
1

Ich versuche, einen Stil für eine Infragistics DataRecordCellArea für eine XamDataGrid zu optimieren weitgehend auf dem aktuell zugewiesenen Stil basiert (über ThemeManager, aber möglicherweise auf ein Elternelement). Normalerweise, wenn das Thema wie das System Themen in der gleichen Art und Weise wurde angewandt wird, würde ich dies mit etwas tun:Wie kann ich auf den impliziten (nicht Standard) Stil für ein UIElement von Code zurück zugreifen?

<!-- with xmlns:idp="http://infragistics.com/DataPresenter" --> 
<Style 
    TargetType="{x:Type idp:DataRecordCellArea}" 
    BasedOn={StaticResource {x:Type idp:DataRecordCellArea}} 
    > 
    <!-- Style overrides --> 
</Style> 

mit dem Stil als eine Ressource auf den XamDataGrid, dass die impliziten in der Hoffnung injiziert wird Stil würde basierend auf dem Attribut BasedOn abgeholt werden. Dies ist jedoch nicht, was passiert: mit diesem Ansatz, bekomme ich eine XamlParseException bezogen auf StaticResource nicht in der Lage, die Ressource zu finden - d. H. Es gibt keinen Stil, um die Dinge auf Basis.

"Großartig", könnten Sie denken, "einfach loswerden basierend darauf und es wird funktionieren." Dies wäre wahr, außer dass das mit einem leeren Stil deutlich das Aussehen des Steuerelements beeinflusst, als eine Abweichung von dem, was das Thema bietet.

Meine beabsichtigte Lösung ist eine benutzerdefinierte MarkupExtension, die einen Namen FrameworkElement und einen Zieltyp verwendet und versucht, den impliziten Stil zu finden, der verwendet werden soll, wenn ich eine Instanz des Zieltyps als untergeordnetes Objekt des Context-Providing erstellen möchte Objekt. Wenn dies der Standard-Stil (oder sogar ein Null-Wert) ist, dann sei es so. Dies sollte auch dann sicher sein, wenn der Stil verwendet wird, da ich nicht auf Änderungen im Kontext reagieren muss, sondern nur den Wert an dem Punkt, an dem der Stil erstellt wird. Ich denke.

Was ich jedoch nicht herausfinden kann, ist, wie man den IMPLICIT-Stil für ein Element abruft, wenn für die eigentliche Stileigenschaft kein expliziter Wert gefunden wird. Finding the default style scheint einfach genug, aber da es keinen Kontext gibt, um die Application.Current.FindResource() Methode zur Verfügung zu stellen, bin ich davon überzeugt, dass dies das Äquivalent von BasedOn Attribut leer sein wird. Umgekehrt erwarte ich, falsche Nullen zu bekommen, wenn ich einfach var implicit = Context.Resources.Contains(TargetType) ? Context.Resources[TargetType] : null; bekomme, dann erwarte ich, nur Stile zu erfassen, die explizite Mitglieder dieses ResourceDictionary und seiner Sammlung von MergedDictionaries sind.

Es gibt eine Möglichkeit für eine weitere Komplikation: nämlich die Möglichkeit, dass der Stil, den ich eigentlich ersetzen möchte, NICHT nur mit dem Typ verschlüsselt werden darf. Zum Beispiel vorstellen, dass das Thema das gleiche Objekt für mehrere Zwecke verwendet werden können, und jede dieser Zwecke hat einen bestimmten Schlüssel Namen, mit dem Stil dann während der ControlTemplate konfiguriert ist für das übergeordnete Objekt zugeordnet, dh

<Style TargetType={XamDataGridOrSomeUnknownChildOfXamDataGrid}> 
    <Style.Setters> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <ControlTemplate.Resources> 
         <Style TargetType="{TheTypeICareAbout}" x:Key="SomeActualKeyedValue" BasedOn="{StaticResource SomeThemeStyleOrKeyToTheDefaultOne}"> 
         <!-- Style definition --> 
         </Style> 
        </ControlTemplate.Resources> 
        ... 
        <TheTypeICareAbout Style="{StaticResource SomeActualKeyedValue}" /> 
        ... 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style.Setters> 
</Style> 

Vorläufig hoffe ich, dass dies NICHT geschieht, aber es gibt zumindest einige Beweise, die darauf hindeuten, dass dies der Fall sein könnte. Wenn jemand einen Weg kennt, den Stil anzuhängen und zu überschreiben, wenn der ControlTemplate gerendert wird, würde dies auch mein Problem beantworten - möglicherweise besser, als den impliziten Stil zu finden (weil ich dann einen impliziten Stil eigentlich nicht überschreibe).

+0

Im letzten Fall ("weitere Komplikation") Stil wird immer 'SomeActualKeyedValue' Ich denke, egal was du tust. – Evk

+0

Meh - hatte gehofft, dass es eine Möglichkeit geben könnte zu sagen "Nehmen wir für dieses Objekt für jede erstellte Instanz meines Zieltyps den Stil, der auf seine eigenen Geräte angewendet werden würde, und konstruiere stattdessen einen neuen, übergeordneten Stil Wende das stattdessen an ". Ich denke, die versiegelte Art der Stile bedeutet, dass Sie für jede Instanz eine neue benötigen, oder zumindest für jeden identifizierten Kandidatenstil, um die neue zu erstellen, aber immer noch. Wenn es nicht möglich ist, ist es nicht möglich. – tobriand

+0

Hmm ... ich denke darüber nach, ob ich die 'FrameworkPropertyMetaData' überschreiben könnte, damit der Zieltyp auf Änderungsereignisse auf einer Basiseigenschaft reagiert, und dann meinen Stil dort anwendet ... Könnte Overkill sein, aber ich schätze es Bedenken Sie ... – tobriand

Antwort

0

Der Ansatz, den ich am Ende nahm (den komplizierenden Fall für jetzt ignorierend), war, eine Markierungserweiterung zu schreiben, die ein FrameworkElement für Kontext und einen Zieltyp nahm. Von dort stellt sich heraus, dass alle FrameworkElements eine FindResource()-Methode haben (nicht nur die Anwendung), so dass es ziemlich einfach war, einfach FindResource aufzurufen, da es sich um das Kontextobjekt handelte.

Das Ergebnis ist XAML, die etwas wie folgt aussieht:

<Style 
    TargetType={x:Type TheTypeIWant} 
    BasedOn={BasedOnWithContext Context={x:ref NameOfContextProvidingObject},TargetType={x:Type TheTypeIWant}} 
    /> 

...und C#, die in etwa so aussieht:

public class BasedOnWithContextExtension : MarkupExtension 
{ 
    public BasedOnWIthContextExtension() 
    { 
    } 

    public DependencyObject Context {get; set;} 

    public Type TargetType {get; set;} 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this.Context?.FindResource(this.TargetType) as Style; 
    } 
} 

(NB die oben eine Annäherung an meiner Lösung ist, da ich die Code-Basis nicht Hand habe, und habe nicht versucht, es für jetzt kompilieren, aber es sollte eine faire Idee hinsichtlich des Ansatzes geben, der funktioniert hat.)

Dies bewertet nett an dem Punkt, an dem der Stil erstellt werden würde, findet den impliziten Stil und baut ihn ab. Es findet keine Stile mit einem unbekannten (oder bekannten) Schlüssel und ersetzt sie (für den komplizierten Fall).

Verwandte Themen