Manage user editable WPF styles

I have some common styles that define how my DataGrids look and I store them in Styles.xaml

I added a settings page that will allow the user to change some colors. On this page, I have a grid selection (which automatically looks like other grids thanks to common resource styles). On this page, the user can use a set of colors to change the colors of attributes, such as row background color, highlighted row colors, header background, and other styles that are applied using data-driven converters.

I would like the style to be applied to the grid of settings pages for preview only, and if applicable, go back to global styles.

I get to the load point of the color set for each custom color and am not sure what to apply the result to.

Should I:

a. apply the selected color directly to the grid? (it seems that only the grid allows me to assign styles dynamically, rather than individual stylists)

b. get a shared resource, copy it and change it in the settings grid, what if the user "applies" to exchange it for a shared resource? (this ideal, in my opinion, but not sure how to do it ..)

from. another way to do it?

+4
source share
1 answer

I would be inclined to handle it like this:

  • Make each grid color a separate resource, and then reference them from the grid styles using DynamicResource.
  • Put them in a separate "Color" ResourceDictionary inside your Styles.xaml (in ResourceDictionary.MergedDictionaries).
  • Define a ColorProxy object that has a Color property that, when set, updates the brush color in ResourceDictionary
  • In the constructor for the settings page, clone the "colors" ResourceDictionary and build a ColorProxy for each color, and then bind them
  • In the "Save" window on the settings page, copy the "Color" ResourceDictionary into the user settings repository, as well as into the main "colors" of the ResourceDictionary.

Most of this is simple, so I will not go into details.

Here is the idea of ​​Styles.xaml:

<ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary> <SolidColorBrush x:Key="Row Background Color" Color="..." /> ... </ResourceDictionary> </ResourceDictionary.MergedDictionaries> <Style TargetType="DataGrid"> ... <Setter Property="Background" Value="{DynamicResource Row Background Color}" /> ... </Style> </ResourceDictionary> 

Here is the code for copying ColorProxy objects:

 public IEnumerable<ColorProxy> ColorProxies { get { return from key in _colorDict.Keys select new ColorProxy { Dictionary=_colorDict, Key=key }; } } 

and ColorProxy itself:

 public class ColorProxy { public ResourceDictionary Dictionary { get; set; } public object Key { get; set; } public Color Value { get { return ((SolidColorBrush)Dictionary[Key]).Color; } set { Dictionary[Key] = new SolidColorBrush { Color = value }; } } } 

Colors in ResourceDictionary can now be edited with:

 <ItemsControl ItemsSource="{Binding ColorProxies}"> <ItemsControl.ItemTemplate> <DataTemplate DataType="local:ColorProxy"> <DockPanel> <TextBlock Text="{Binding Key}" Width="200" /> <ColorPicker Color="{Binding Color}" /> </DockPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 

The modified ResourceDictionary can be converted to a string for storage using XamlWriter and reloaded using XamlReader.

The MergedDictionaries collection of basically ResourceDictionary generated by Styles.xaml can be changed by calling .Remove () in the old dictionary and .Add () on the new.

ResourceDictionaries can be cloned simply by creating a new ResourceDictionary, iterating over entries in the old dictionary and adding them to the new one.

This method should not be limited to editing colors. Any proxy objects can be created, including general ones, where data conversion is processed by the converter in a binding.

+1
source

Source: https://habr.com/ru/post/1314194/


All Articles