2013-03-06 13 views
6

ho seguito UserControl:Override in XAML

<UserControl x:Class="MyControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 

    <UserControl.Resources> 
     <SolidColorBrush x:Key="ColorKey" Color="Orange"/> 
    </UserControl.Resources> 

    <Grid Background="{StaticResource ColorKey}"> 

    </Grid> 
</UserControl> 

e lo uso come questo:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:OverrideResource" 
    Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 
     <SolidColorBrush x:Key="OtherColorKey" Color="Blue"/> 
    </Window.Resources> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 

     <local:MyControl Grid.Row="0"> 
      <local:MyControl.Resources> 
       <SolidColorBrush x:Key="ColorKey" Color="Red"/> 
      </local:MyControl.Resources> 
     </local:MyControl> 

     <Grid Grid.Row="1"> 
      <Grid.Resources> 
       <SolidColorBrush x:Key="OtherColorKey" Color="Green"/> 
      </Grid.Resources> 
      <Grid Background="{StaticResource OtherColorKey}"/> 
     </Grid> 
    </Grid> 
</Window> 

prioritario di risorse OtherColorKey opere come mi aspetto; la griglia è verde Background. Ma vorrei scavalcare un Resource che viene utilizzato all'interno del UserControl (ColorKey nel mio esempio). Ma sto ricevendo un'eccezione:

L'articolo è già stato aggiunto. Chiave nel dizionario: chiave "ColorKey" aggiunta: "ColorKey"

Questo è solo un esempio semplificato, in realtà ne ho bisogno per un compito un po 'più complesso. So che per l'esame DevExpress utilizza un meccanismo simile per la personalizzazione dei loro controlli (tuttavia non usano stringhe come chiavi, ma oggetti derivati ​​da ResourceKey). Ma non sono in grado di trovare un semplice esempio di lavoro per implementare tale cosa da solo.

Grazie per il vostro aiuto.

risposta

0

OtherColorKey viene aggiunto a 2 dizionari diversi (finestra e griglia). ColorKey viene aggiunto allo stesso dizionario (MyControl).

Un modo migliore per avvicinarsi a questo sarebbe di dichiarare un DependencyProperty di tipo pennello all'interno MyControl e impostarlo come:

<local:MyControl Grid.Row="0" MyBrush="Red" /> 

All'interno MyControl, basta associare quello che vuoi che la proprietà MyBrush.

<UserControl x:Class="MyControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300" x:Name=Me> 

    <Grid Background="{Binding MyBrush, ElementName=Me}"> 

    </Grid> 
</UserControl> 
+2

Grazie, so che posso aggiungere nuove proprietà di dipendenza e risolverlo in questo modo. Ma come ho scritto, quello che ho postato è solo un esempio semplificato. Immagina di avere non solo un singolo pennello come risorsa, ma diversi controltemplates, stili o altre risorse. Non voglio aggiungere proprietà di dipendenza per ogni risorsa che voglio "sovrascrivere". – Stalker

4

Dopo aver letto il tuo post, e rispondere alla prima risposta a quanto pare si sta scrivendo un'applicazione che si richiede all'utente di tenere traccia di diversi elementi stilistici. Il modo migliore per mantenerli organizzati e facilmente manutenibili è usare un ResourceDictionary e fare riferimento ad esso.

Per me, ho un tempo molto più semplice quando separo il mio in base a ciò che stanno definendo, uno per i pennelli ei colori e uno per i ControlTemplates e gli stili (se il progetto è estremamente complicato, dipende da diversi altri fattori - questo è solo per un progetto relativamente semplice).

Una volta che questi file ResourceDictionary sono state definite, li si dovrebbe fare riferimento nel file App.xaml in modo che possano essere applicati in tutta l'applicazione, senza dover ridefinire sempre un pennello o un modello in XAML effettivo della pagina.

Così, un esempio di come l'App.xaml può apparire:

<Application 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    x:Class="MyColorBlock.App" 
    StartupUri="MainWindow.xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Resources/BrushesAndColors.xaml"/> 
       <ResourceDictionary Source="Resources/StylesAndTemplates.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

Come detto, questo è un esempio molto semplificato, in modo che i file di origine si trovano nello stesso progetto l'App.xaml è - solo nella cartella Risorse. A BrushesAndColors.xaml viene fatto riferimento prima di StylesAndTemplates.xaml poiché gli stili e i modelli definiti dipendono dai colori definiti.

Per il ResourceDictionary BrushesAndColors.XAML:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:OverrideResource"> 

     <SolidColorBrush x:Key="BlueBrush" Color="Blue"/> 
     <SolidColorBrush x:Key="RedBrush" Color="Red"/> 
     <SolidColorBrush x:Key="GreenBrush" Color="Green"/> 

</ResourceDictionary> 

le spazzole sono lo stesso come è stata definita, ma che ora possono solo fare riferimento per la loro chiave in tutta l'applicazione.

Per la StylesAndTemplates.xaml:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:OverrideResource"> 

    <!-- Adding the MergedDictionaries in this ResourceDictionary allows the control templates and styles to reference the colors and brushes defined in BrushesAndColors.xaml. Note: It is a relative link, both files in this example in the same folder "Resources" --> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="BrushesAndColors.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 

    <Style x:key="MyControlStyle" TargetType="{x:Type local:MyControl}"> 
     <Setter Property="HorizontalAlignment" Value="Stretch"/> 
     <Setter Property="VerticalAlignment" Value="Stretch"/> 
     <Setter Property="Background" Value="{StaticResource RedBrush}"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:MyControl}"> 
       <!-- by giving the border background the value of {TemplateBinding Background} it is now set based on what the style's property has been defined as --> 
        <Border Background="{TemplateBinding Background}"> 
         <TextBlock Text="Red Block Text"/> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 


    <!-- since the style is based on a predefined one it inherits that particular style's definition. 
     However, the background color of this stylehas been redefined, and will use that background color 
     on any control it is applied to instead--> 

    <Style x:Key="MyControlStyleTwo" TargetType="{x:Type local:MyControl}" BasedOn="{StaticResource MyControlStyle}"> 
     <Setter Property="Background" Value="{StaticResource BlueBrush}"/> 
    </Style> 


</ResourceDictionary> 

Per abitudine, ho ancora riferimento alla ResourceDictionary che questo ha bisogno di fare in modo che gli stili e modelli definiti in grado di trovare le risorse che fanno riferimento a quando la loro creazione.

Il secondo stile, l'ho basato sulla prima, quindi non devo riscrivere l'intera cosa, ma posso semplicemente cambiare il colore dello sfondo. Quindi assomiglierà al primo tranne con un diverso colore di sfondo.

per la finestra principale - che cambierà leggermente:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:OverrideResource" 
    Title="MainWindow" Height="350" Width="525"> 

    <Grid Background="{StaticResource BlueBrush}"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 

     <local:MyControl Style="{StaticResource MyControlStyle}" Grid.Row="0" /> 
     <local:MyControl Style="{StaticResource MyControlStyleTwo}" Grid.Row="1"/> 

    </Grid> 
</Window> 

Non è più di ridefinire tutte le informazioni relative alla interfaccia utente dell'applicazione, mantenendo il più pulito XAML e più facile da leggere.

Potrebbe non essere la "soluzione facile", ma sicuramente renderà le cose molto più semplici mentre continui. Aiuterà anche chiunque altro se più di una persona sta lavorando al progetto. Con tutto ciò che è definito in un'area centralizzata, è possibile mantenere coerenti stili e colori e nessuno deve setacciare pagine diverse per trovare lo stile utilizzato, facendo semplicemente riferimento a quello appropriato.

Ciò consente anche per il controllo da scrivere solo una volta, ma dandogli diversi stili/modelli si è in grado di cambiare la modalità di visualizzazione delle informazioni - contribuendo a mantenere i dati e le informazioni sul display separato :)

Spero che questo aiuti, mi spiace per il post lungo, ma era l'unico modo in cui potevo pensare di spiegare come penso che potresti risolvere al meglio il tuo problema (e tenerlo risolto).