【问题标题】:managing user editable WPF styles管理用户可编辑的 WPF 样式
【发布时间】:2010-06-29 12:18:10
【问题描述】:

我有一些共享样式,它们定义了我的 DataGrid 的外观,我将它们保存在 Styles.xaml 中

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

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

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

我应该:

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

b.获取共享资源,复制它,然后在设置网格中交换它,而不是用户“应用”将它交换为共享资源? (这在我看来是理想的,但不知道如何做到这一点..)

c。另一种方法?

【问题讨论】:

    标签: wpf styling


    【解决方案1】:

    我会倾向于这样处理:

    1. 将每个网格颜色设为单独的资源,然后使用 DynamicResource 从网格样式中引用它们。
    2. 将这些放在 Styles.xaml 中的单独“颜色”ResourceDictionary 中(在 ResourceDictionary.MergedDictionaries 下)
    3. 定义一个具有 Color 属性的 ColorProxy 对象,该属性在设置后会更新 ResourceDictionary 中画笔的颜色
    4. 在设置页面的构造函数中,克隆“colors”ResourceDictionary并为每种颜色构造一个ColorProxy,然后绑定它们
    5. 在设置页面的“保存”按钮中,将“colors”ResourceDictionary 复制到您的用户设置存储区以及主“colors”ResourceDictionary

    大部分内容都很简单,所以我不会详细介绍。

    这是 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() 来修改。

    ResourceDictionaries 可以通过简单地构造一个新的 ResourceDictionary 来复制旧字典中的条目并将它们添加到新字典中。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多