将应用程序资源中的 DependancyProperty 绑定到控件 DependancyProperty(正在使用该资源)

Binding a DependancyProperty from an Application resource to a Control DependancyProperty (that is using the resource)

我正在尝试构建一个自定义的 class 继承自图像控件,但我在绑定时遇到了一些问题。

我在我的资源中使用 DrawingImage(这是为矢量图像提供的)

所以在我的 App.xaml 资源中我有一些 DrawingImages,例如:

<DrawingImage x:Key="Shutdown">
            <DrawingImage.Drawing>
                <DrawingGroup>
                    <DrawingGroup.Children>
                        <DrawingGroup>
                            <DrawingGroup.Children>
                                <GeometryDrawing Brush="{x:Null}">
                                    <GeometryDrawing.Pen>
                             Here-->    <Pen Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Thickness="2" />
                                    </GeometryDrawing.Pen>
                                    <GeometryDrawing.Geometry>
                                        <PathGeometry FillRule="Nonzero" Figures="M8.332,4.941C5.759,6.271 4,8.956 4,12.052 4,16.47 7.582,20.052 12,20.052 16.418,20.052 20,16.47 20,12.052 20,8.911 18.19,6.193 15.555,4.884" />
                                    </GeometryDrawing.Geometry>
                                </GeometryDrawing>
                       Here-->  <GeometryDrawing Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Pen="{x:Null}">
                                    <GeometryDrawing.Geometry>
                                        <RectangleGeometry RadiusX="0" RadiusY="0" Rect="11,2,2,10" />
                                    </GeometryDrawing.Geometry>
                                </GeometryDrawing>
                            </DrawingGroup.Children>
                            <DrawingGroup.ClipGeometry>
                                <RectangleGeometry Rect="0,0,24,24" />
                            </DrawingGroup.ClipGeometry>
                        </DrawingGroup>
                    </DrawingGroup.Children>
                </DrawingGroup>
            </DrawingImage.Drawing>
        </DrawingImage>

我已经按照如下方式构建了自定义 class:

 public class IconImage : Image
{
    public enum Icons
    {
        None,
        Shutdown,
        Minimize
    }

    private Icons _icon;
    public Icons Icon
    {
        get { return _icon; }
        set
        {
            _icon = value;
            if (value == Icons.None)
            {
                Visibility = Visibility.Hidden;
            }
            else
            {
                Visibility = Visibility.Visible;
                this.SetResourceReference(Image.SourceProperty, value.ToString());
            }
        }
    }

    public static readonly DependencyProperty ColourProperty = DependencyProperty.Register("Colour", typeof(Brush), typeof(IconImage), new PropertyMetadata(Brushes.Black));

    public Brush Colour
    {
        get { return (Brush)GetValue(ColourProperty); }
        set { SetValue(ColourProperty, value); }
    }
}

用法:

<local:IconImage Icon="Shutdown" Colour="CornflowerBlue" />

问题是我在 DrawingImages 中的 Brush 绑定不会绑定到我在自定义 class 中的 Color DependancyProperty,我不知道如何完成这个,或者,如果它可能的话。如果我对画笔进行硬编码,它就可以完美地工作(很明显)。我只需要能够在设计时或在后面的代码中随时从控件更改它们的颜色。

提前致谢!

-肖恩-

<local:IconImage Icon="Shutdown" Colour="CornflowerBlue">
    <local:IconImage.Source>
        <DrawingImage>
            <DrawingImage.Drawing>
                <DrawingGroup>
                    <DrawingGroup.Children>
                        <DrawingGroup>
                            <DrawingGroup.Children>
                                <GeometryDrawing Brush="{x:Null}">
                                    <GeometryDrawing.Pen>
                                        <Pen Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Thickness="2" />
                                    </GeometryDrawing.Pen>
                                    <GeometryDrawing.Geometry>
                                        <PathGeometry FillRule="Nonzero" Figures="M8.332,4.941C5.759,6.271 4,8.956 4,12.052 4,16.47 7.582,20.052 12,20.052 16.418,20.052 20,16.47 20,12.052 20,8.911 18.19,6.193 15.555,4.884" />
                                    </GeometryDrawing.Geometry>
                                </GeometryDrawing>
                                <GeometryDrawing Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Pen="{x:Null}">
                                    <GeometryDrawing.Geometry>
                                        <RectangleGeometry RadiusX="0" RadiusY="0" Rect="11,2,2,10" />
                                    </GeometryDrawing.Geometry>
                                </GeometryDrawing>
                            </DrawingGroup.Children>
                            <DrawingGroup.ClipGeometry>
                                <RectangleGeometry Rect="0,0,24,24" />
                            </DrawingGroup.ClipGeometry>
                        </DrawingGroup>
                    </DrawingGroup.Children>
                </DrawingGroup>
            </DrawingImage.Drawing>
        </DrawingImage>
    </local:IconImage.Source>
</local:IconImage>

你可以让它像这样工作。首先将资源标记为非共享,因为你想让你的 DrawingImage 根据它所属的 IconImage 改变外观,这对共享资源没有多大意义(在这种情况下共享意味着像单例 - 只有一个全局实例):

<DrawingImage x:Key="Shutdown" x:Shared="False">
    <!-- the rest -->
</DrawingImage>

然后不使用 SetResourceReference 而是这样做:

var resource = FindResource(value.ToString());
// alternative
// var resource = Application.Current.Resources[value.ToString()];
this.Source = (ImageSource)resource;     

这与将您的 DrawingImage xaml 直接放在 IconImage 下大致相同,就像其他答案建议的那样。

顺便说一句,您最好为您的资源取更多唯一的名称,以避免在树下意外使用同名资源(尤其是如果您打算使用 FindResource)。