C# 根据枚举将Shape.Stroke绑定到ResourceDictionary

C# 根据枚举将Shape.Stroke绑定到ResourceDictionary,c#,wpf,xaml,enums,C#,Wpf,Xaml,Enums,我创建了这个资源字典: <LinearGradientBrush x:Key="OffStroke" EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF007226" Offset="0"/> <GradientStop Color="#FF003C15" Offset="1"/> </LinearGradientBrush> <LinearGradie

我创建了这个资源字典:

 <LinearGradientBrush x:Key="OffStroke" EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF007226" Offset="0"/>
    <GradientStop Color="#FF003C15" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="OnStroke" EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF6BBF8A" Offset="0"/>
    <GradientStop Color="#FF007A27" Offset="0.306"/>
</LinearGradientBrush>
是否可以根据枚举值将Ellipse Stroke属性绑定到Stroke ResourceDictionary


如果您在资源字典中这样定义渐变笔刷,请提前感谢:

xmlns:enums="clr-namespace:MyNamespace.Enums" ...

<LinearGradientBrush x:Key="{x:Static enums:Strokes.Off}" EndPoint="0.5,1" StartPoint="0.5,0">
  <GradientStop Color="#FF007226" Offset="0"/>
  <GradientStop Color="#FF003C15" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="{x:Static enums:Strokes.On}" EndPoint="0.5,1" StartPoint="0.5,0">
  <GradientStop Color="#FF6BBF8A" Offset="0"/>
  <GradientStop Color="#FF007A27" Offset="0.306"/>
</LinearGradientBrush>
现在可以使用转换器绑定到属性值,如下所示:

xmlns:enums="clr-namespace:MyNamespace.Enums" ...

<LinearGradientBrush x:Key="{x:Static enums:Strokes.Off}" EndPoint="0.5,1" StartPoint="0.5,0">
  <GradientStop Color="#FF007226" Offset="0"/>
  <GradientStop Color="#FF003C15" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="{x:Static enums:Strokes.On}" EndPoint="0.5,1" StartPoint="0.5,0">
  <GradientStop Color="#FF6BBF8A" Offset="0"/>
  <GradientStop Color="#FF007A27" Offset="0.306"/>
</LinearGradientBrush>
MyControl.xaml

或者,您可以放弃任何绑定,只使用触发器来完成大致相同的事情。下面是一个示例样式,展示了如何实现这一点:

Themes/Generic.xaml

xmlns:enums=“clr namespace:MyNamespace.enums”。。。
在…上
关

这是如何在窗口中使用的控件中使用

在初始化组件之前,将此行放入UserControl的构造函数中 假设您的ResourcesDictionary文件名为StrokeResources.xaml

 //merge the control resources used to current application 
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary(){Source = new Uri("/DLLNameSpace;component/ResourcesDictionaries/StrokeResources.xaml", UriKind.RelativeOrAbsolute)}); 
然后修改xaml代码:

<Ellipse Stroke="{Binding StrokeX, Converter={StaticResource ApplicationResourceConverter}}"/>


通过这种方式,资源被添加到实际的应用程序中…

非常感谢您的回答,只需一个简短的类内修改转换器,我就把它放在类“[ValueConversion(typeof(Enum.Strokes),typeof(Brush))]”上,并向返回的值添加强制转换:“return(Brush)application.Current.resources[value];”p、 s.w.g.只有在窗口中使用此代码时,此功能才有效。但是如果我像使用Usercontrol一样使用它,然后将这个控件插入到窗口中。此代码不起作用我在用户控件内部工作时没有遇到任何问题。我已经在更新的答案中发布了用户控件的完整源代码。另外,我不认为
ValueConversion
属性是绝对必要的,实际上我认为让它保持原样更有用,这样您就可以将它用于不同类型的资源或键。是的,我完全同意您的看法,您的情况不像我的转换器那样典型化。但是如果我想在另一个程序集中使用你的控件,我需要从外部dll合并字典,不是吗?@luka你不需要为你的资源动态注册
xaml
文件。我认为期望任何消费应用程序在设计时添加适当的样式或提供自己的主题是合理的。在任何情况下,再仔细考虑一下,我会说,在这种情况下,触发器可能会更直接。有关示例,请参见我的更新答案。
<Ellipse x:Name="OnStroke" Stroke="{StaticResource {x:Static enums:Strokes.On}}"/>
<Ellipse x:Name="OffStroke" Stroke="{StaticResource {x:Static enums:Strokes.On}}"/> 
public class ApplicationResourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Application.Current.Resources[value];
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
<UserControl x:Class="MyNamespace.MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyNamespace"
             xmlns:converters="clr-namespace:MyNamespace.Converters">
  <UserControl.Resources>
    <converters:ApplicationResourceConverter x:Key="ApplicationResourceConverter"/>
  </UserControl.Resources>
  <StackPanel  Grid.Row="1" Grid.Column="2">
    <Ellipse Stroke="{Binding StrokeX, RelativeSource={RelativeSource AncestorType=local:MyControl}, Converter={StaticResource ApplicationResourceConverter}}"
             StrokeThickness="5"
             Fill="AliceBlue"
             Width="100"
             Height="100"
             Margin="0 0 0 20"/>
    <StackPanel Orientation="Horizontal">
      <Button Click="OnButton_Click">On</Button>
      <Button Click="OffButton_Click">Off</Button>
    </StackPanel>
  </StackPanel>
</UserControl>
public partial class MyControl : UserControl
{
    public MyControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty StrokeXProperty =
        DependencyProperty.Register("StrokeX", typeof(Enums.Strokes), typeof(MyControl), new PropertyMetadata(Enums.Strokes.Off));

    public Enums.Strokes StrokeX
    {
        get { return (Enums.Strokes)GetValue(StrokeXProperty); }
        set
        {
            SetValue(StrokeXProperty, value);
        }
    }

    private void OnButton_Click(object sender, RoutedEventArgs e)
    {
        this.StrokeX = Enums.Strokes.On;
    }

    private void OffButton_Click(object sender, RoutedEventArgs e)
    {
        this.StrokeX = Enums.Strokes.Off;
    }
}
xmlns:enums="clr-namespace:MyNamespace.Enums" ...

<LinearGradientBrush x:Key="{x:Static enums:Strokes.Off}" EndPoint="0.5,1" StartPoint="0.5,0">
  <GradientStop Color="#FF007226" Offset="0"/>
  <GradientStop Color="#FF003C15" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="{x:Static enums:Strokes.On}" EndPoint="0.5,1" StartPoint="0.5,0">
  <GradientStop Color="#FF6BBF8A" Offset="0"/>
  <GradientStop Color="#FF007A27" Offset="0.306"/>
</LinearGradientBrush>

<Style x:Key="{x:Type local:MyControl}" TargetType="local:MyControl">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="local:MyControl">
        <StackPanel  Grid.Row="1" Grid.Column="2">
          <Ellipse Name="_ellipse"
                   StrokeThickness="5"
                   Fill="AliceBlue"
                   Width="100"
                   Height="100"
                   Margin="0 0 0 20"/>
          <StackPanel Orientation="Horizontal">
            <Button Click="OnButton_Click">On</Button>
            <Button Click="OffButton_Click">Off</Button>
          </StackPanel>
        </StackPanel>
        <ControlTemplate.Triggers>
          <Trigger Property="StrokeX" Value="{x:Static enums:Strokes.On}">
            <Setter TargetName="_ellipse" Property="Stroke" Value="{DynamicResource {x:Static enums:Strokes.On}}"/>
          </Trigger>
          <Trigger Property="StrokeX" Value="{x:Static enums:Strokes.Off}">
            <Setter TargetName="_ellipse" Property="Stroke" Value="{DynamicResource {x:Static enums:Strokes.Off}}"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
 //merge the control resources used to current application 
        Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary(){Source = new Uri("/DLLNameSpace;component/ResourcesDictionaries/StrokeResources.xaml", UriKind.RelativeOrAbsolute)}); 
<Ellipse Stroke="{Binding StrokeX, Converter={StaticResource ApplicationResourceConverter}}"/>