WPF:无法通过绑定在资源中设置颜色

时间:2015-05-09 09:09:04

标签: c# .net wpf xaml

我们在应用程序中有xaml资源形式的不同图标,如下所示:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DrawingBrush x:Key="My_Icon">
    <DrawingBrush.Drawing>
        <GeometryDrawing Brush="Gray"> <!--I want to set this Brush here using binding-->
            <GeometryDrawing.Geometry>
                <GeometryGroup>
                    <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
                    <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
                </GeometryGroup>
            </GeometryDrawing.Geometry>
        </GeometryDrawing>
    </DrawingBrush.Drawing>
</DrawingBrush>

我们在另一个xaml文件中使用这些资源(在代码中加载此资源,请参阅下面的代码)

public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();

        var resource = Application.Current.FindResource("My_Icon");
        this.MyBrush = resource as DrawingBrush;

        NewBrush = Brushes.Blue;

        this.DataContext = this;
    }

    private DrawingBrush _myBrush;

    public DrawingBrush MyBrush
    {
        get { return _myBrush; }
        set { _myBrush = value; }
    }

    private Brush _newBrush;

    public Brush NewBrush
    {
        get { return _newBrush; }
        set { _newBrush = value; }
    }
}

问题是,我无法使用绑定设置图标颜色(在资源代码中,第一个代码片段),在ViewModel中具有属性(在这种情况下,在Window2代码中的MyBrush属性)

我尝试使用资源文件中的以下代码:

<GeometryDrawing Brush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Rectangle}, Path=NewBrush}">

但这不起作用。我可能会在这里失踪。

1 个答案:

答案 0 :(得分:1)

我想出了两种解决问题的方法。

解决方案我(我认为更好)

放弃代码隐藏方法并将资源字典直接导入窗口资源,并使用StaticResourceExtension引用资源:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="TheNameOfYourDictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
...
<Rectangle Fill="{StaticResource My_Icon}"/>

当您这样做并使用AncestorType=local:Window2时,您的绑定应该有效(尽管在当前形状中,对NewBrush属性的后续更改不会反映在图形中 - 请参阅最后的列表这个答案)。请注意,有必要使用{StaticResource My_Icon}代替{Binding MyBrush}

解决方案II

在代码隐藏中设置绑定:

var resource = Application.Current.FindResource("My_Icon");
this.MyBrush = resource as DrawingBrush;

NewBrush = Brushes.Blue;

BindingOperations.SetBinding(MyBrush.Drawing, GeometryDrawing.BrushProperty,
    new Binding { Path = new PropertyPath("NewBrush"), Source = this });

请注意,为了使这个(或第一个解决方案)起作用,应满足以下条件之一:

    在设置绑定之前设置
  1. NewBrush(在第一个解决方案的情况下设置DataContext之前)
  2. Window2实施INotifyPropertyChanged并在PropertyChanged设置后引发NewBrush事件
  3. NewBrush是依赖属性