如何在不违反MVVM的情况下绑定到不可绑定的属性?

时间:2016-01-27 12:04:56

标签: c# wpf svg mvvm data-binding

我正在使用SharpVector's SvgViewBox来显示如下的静态资源图片:

<svgc:SvgViewbox Source="/Resources/label.svg"/>

工作正常。但是,我希望通过绑定到视图模型来控制显示的图像。

我遇到的问题是SvgViewbox的Source属性不可绑定。

如何在不违反MVVM的情况下解决此限制(例如,将控件传递给视图模型并在其中进行修改)?

1 个答案:

答案 0 :(得分:7)

您正在寻找的是被称为附加属性。 MSDN提供了一个标题为&#34; Custom Attached Properties&#34;

的主题

在您的情况下,它可能看起来像这个

一样简单
namespace MyProject.Extensions 
{
    public class SvgViewboxAttachedProperties : DependencyObject
    {
        public static string GetSource(DependencyObject obj)
        {
            return (string) obj.GetValue(SourceProperty);
        }

        public static void SetSource(DependencyObject obj, string value)
        {
            obj.SetValue(SourceProperty, value);
        }

        private static void OnSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var svgControl = obj as SvgViewbox;
            if (svgControl != null)
            {
                var path = (string)e.NewValue;
                svgControl.Source = string.IsNullOrWhiteSpace(path) ? default(Uri) : new Uri(path);
            }                
        }

        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.RegisterAttached("Source",
                typeof (string), typeof (SvgViewboxAttachedProperties),
                                    // default value: null
                new PropertyMetadata(null, OnSourceChanged));
    }
}

XAML使用它

<SvgViewbox Margin="0 200" 
    local:SvgViewboxAttachedProperties.Source="{Binding Path=ImagePath}" />

请注意,local是名称空间前缀,它应指向该类所在的程序集/命名空间,即xmlns:local="clr-namespace:MyProject.Extensions;assembly=MyProject"

然后只使用附加属性(local:Source)而不使用Source属性。

新附加属性local:Source的类型为System.Uri。要更新映像,首先再分配null,然后再次分配文件名/文件路径。