管理用户可编辑的WPF样式

时间:2010-06-29 12:18:11

标签: wpf styling

我有一些共享样式,用于定义我的DataGrids的外观,并将其保留在Styles.xaml中

我添加了一个设置页面,让用户可以更改一些颜色。在那个页面上,我有一个示例网格(由于共享资源样式,它自动看起来像其他网格)。在该页面上,用户可以使用颜色选择器来修改属性的颜色,例如行背景颜色,突出显示的行颜色,标题背景以及使用数据驱动转换器应用的其他样式。

我希望样式仅应用于设置页面网格以进行预览,如果应用,则返回到全局样式。

我一直到为每种可配置颜色加载颜色选择器,并且不确定将结果应用于什么。

我应该:

一个。将所选颜色直接应用于网格? (似乎网格只允许我动态分配样式,而不是单独的样式设置器)

湾获取共享资源,复制它,并在设置网格中交换它,而不是用户“应用”交换共享资源? (这个在我看来是理想的,但不知道该怎么做..)

℃。这样做的另一种方式?

1 个答案:

答案 0 :(得分:1)

我倾向于这样处理:

  1. 将每个网格颜色设置为单独的资源,然后使用DynamicResource从网格样式中引用它们。
  2. 将它们放在Styles.xaml中的单独“colors”ResourceDictionary中(在ResourceDictionary.MergedDictionaries下)
  3. 定义具有Color属性的ColorProxy对象,该属性在设置时更新ResourceDictionary中画笔的颜色
  4. 在设置页面的构造函数中,克隆“colors”ResourceDictionary并为每种颜色构造一个ColorProxy,然后绑定它们
  5. 在设置页面的“保存”按钮中,将“colors”ResourceDictionary复制到用户设置存储区,并复制到主要的“colors”ResourceDictionary
  6. 大部分内容都是直截了当的,所以我不会详细介绍。

    以下是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>
    

    以下是复制构造ColorProxy对象的代码:

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

    和ColorProxy本身:

    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 }; }
      }
    }
    

    现在可以使用以下命令编辑ResourceDictionary中的颜色:

    <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>
    

    可以使用XamlWriter将编辑后的ResourceDictionary转换为字符串进行存储,并使用XamlReader重新加载。

    Styles.xaml生成的主要ResourceDictionary中的MergedDictionaries集合可以通过在旧字典上调用.Remove()和在新字典上调用.Add()来修改。

    可以通过简单地构建一个新的ResourceDictionary来克隆ResourceDictionaries,迭代旧字典中的条目并将它们添加到新字典中。

    此技术不必限于编辑颜色。可以创建任何类型的代理对象,包括通用的代理对象,其中数据转换由绑定中的转换器处理。