管理用户可编辑的 WPF 样式

发布于 2024-09-07 15:16:53 字数 447 浏览 0 评论 0原文

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

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

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

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

我应该

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

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

)另一种方法来做到这一点?

I have some shared styles which define how my DataGrids look and i keep them in Styles.xaml

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

I would like the style to be applied on the settings page grid only for a preview, and if applied, back to global styles.

i am all the way up to the point of loading a color picker for each configurable color, and not sure what to apply the result to.

Should i:

a. apply the selected color directly to the grid? (seems like grid only lets me assign styles dynamically, and not individual style setters)

b. get shared resource, copy it, and swap it in settings grid, than if user "applies" swap it for shared resource? (this one is ideal in my opinion, but not sure how to do this..)

c. another way of doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请持续率性 2024-09-14 15:16:53

我倾向于这样处理:

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

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

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

I would be inclined to handle it this way:

  1. Make each grid color a separate resource, then reference them from the grid styles using DynamicResource.
  2. Put these in a separate "colors" ResourceDictionary inside your Styles.xaml (under ResourceDictionary.MergedDictionaries)
  3. Define a ColorProxy object that has a Color property that, when set, updates the color of a brush in a ResourceDictionary
  4. In the constructor for the settings page, clone the "colors" ResourceDictionary and construct a ColorProxy for each color, and then bind them
  5. In the "Save" button for the settings page, copy the "colors" ResourceDictionary to your user settings storage and also into the main "colors" ResourceDictionary

Most of this is straightforward, so I won't go into too much detail.

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 code to copy the construct the 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 }; }
  }
}

The colors in the 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 edited ResourceDictionary can be converted to a string for storage using XamlWriter and reloaded using XamlReader.

The MergedDictionaries collection in the main ResourceDictionary generated by Styles.xaml can be modified by calling .Remove() on the old dictionary and .Add() on the new one.

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

This technique need not be limited to editing colors. Any kind of proxy objects can be created, including generic ones where the data conversion is handled by a converter in the binding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文