Domanda

Ho una BaseSkin e più UserSkin in una dll separata dalla mia applicazione WPF.

A seconda di chi sta usando l'applicazione, la skin di base e una delle skin dell'utente verranno unite in un dizionario di risorse e caricate per l'applicazione da utilizzare.

Ciò a cui sto puntando è la possibilità di specificare uno stile in un file BaseSkin, e quindi su un file UserSkin specifico essere in grado di sovrascriverlo, modificando tutte le proprietà necessarie.

So di poterlo fare usando l'attributo BasedOn in questo modo:

Base:

<Style x:Key="ButtonBg" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/>
</Style>

Utente:

<Style x:Key="CustomButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBg}">
    <Setter Property="Background" Value="Blue"/>
</Style>

Il problema è che ora gli elementi devono avere uno stile di CustomButtonBg che potrebbe non essere effettivamente implementato. Esiste un modo per fare in modo che entrambi gli stili utilizzino la stessa chiave (ButtonBg) e quando vengono uniti, l'applicazione cerca prima uno stile denominato ButtonBg nell'Utente e, se uno non esiste, utilizza quello in base?

Stavo pensando che se potessi dare il nome dell'assembly nell'attributo BasedOn per puntare al file BaseSkin, potrei evitare errori di denominazione quando fornisco loro la stessa chiave, ma non riesco a trovare alcun modo per farlo. Le altre opzioni consistono nel forzare un'implementazione di ogni stile anche se non viene modificato nulla, oppure controllare programmaticamente nelle skin, ma quelle sono le ultime risorse.

È stato utile?

Soluzione

Potresti provare a sfruttare la logica di ricerca delle risorse. Quando WPF sta cercando di trovare una risorsa tramite la chiave, cerca prima nell'elemento ResourceDictionary dell'elemento corrente, poi i suoi genitori, poi i genitori di quello e così via.

Quindi, dal momento che hai detto che è condizionale per l'utente, potrebbe essere unito nel ResourceDictionary a livello Window mentre la tua base originale è nell'applicazione livello.

Modifica: ho informazioni migliori. Da MSDN su dizionari uniti :

  

Comportamento di dizionario unito

     

Le risorse in un dizionario unito occupano una posizione nell'ambito della ricerca delle risorse che si trova subito dopo l'ambito del dizionario delle risorse principale in cui vengono unite. Sebbene una chiave di risorsa debba essere univoca all'interno di ogni singolo dizionario, una chiave può esistere più volte in un insieme di dizionari uniti. In questo caso, la risorsa che viene restituita proviene dall'ultimo dizionario trovato in sequenza nella raccolta MergedDictionaries. Se la raccolta MergedDictionaries è stata definita in XAML, l'ordine dei dizionari uniti nella raccolta è l'ordine degli elementi come indicato nel markup. Se una chiave è definita nel dizionario primario e anche in un dizionario che è stato unito, la risorsa restituita verrà dal dizionario primario. Queste regole di ambito si applicano sia ai riferimenti alle risorse statiche che ai riferimenti dinamici delle risorse.

Ciò significa che puoi definire il tuo skin Base in un ResourceDictionary diverso e unirlo in un altro ResourceDictionary . Inserisci la skin dell'utente in quest'ultima e la troverà per prima, altrimenti continuerà a eseguire il drill down sul dizionario unito che contiene Base. Ognuno dei tuoi dizionari utente può unire il dizionario di base e devi solo caricare il dizionario dell'utente nell'app anziché in entrambi separatamente.

Altri suggerimenti

Potresti semplicemente nominare la tua Base come BaseButtonBg e quando non unisci un ResourceDictionary basato sull'utente unisci uno generico contenente:

<Style x:Key="ButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonBg}"/>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top