如何设计WPF依赖项属性以支持图像路径?

Sco*_*son 4 .net c# wpf user-controls dependency-properties

为了描述我的问题,我创建了一个小应用程序。首先,用户控件:

<UserControl x:Class="WpfApplication10.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="This" DataContext="{Binding ElementName=This}"
    >    
    <Image Source="{Binding Path=MyImageSource}" ></Image>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

第二个TestApp:

<Window x:Class="WpfApplication10.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfApplication10="clr-namespace:WpfApplication10"
    Title="Window1" Height="300" Width="300">
    <WpfApplication10:UserControl1
        MyImageSource="c:\test.png" >        
    </WpfApplication10:UserControl1>
</Window>
Run Code Online (Sandbox Code Playgroud)

第三条用户控件背后的代码

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace WpfApplication10
{
    public partial class UserControl1 : UserControl
    {
        public static readonly DependencyProperty MyImageSourceProperty =
            DependencyProperty.Register("MyImageSource", 
                 typeof(BitmapImage),typeof(UserControl1),
                 new FrameworkPropertyMetadata((BitmapImage)new BitmapImage(),
                      FrameworkPropertyMetadataOptions.None
                 ));

        public BitmapImage MyImageSource
        {
            get { return (BitmapImage)GetValue(MyImageSourceProperty); }
            set { SetValue(MyImageSourceProperty, value); }
        }


        public UserControl1()
        {
            InitializeComponent();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道类型DP的BitMapImage不能以这种方式工作,但是我想知道如何以一种干净的,类型保存的方式来实现此功能。我想要达到与原始Image.Source实现相同的行为。

预先感谢,斯科特

Yog*_*esh 5

在您的控件中,将您的图片命名为:

<Image x:Name="someImage" Source="{Binding Path=MyImageSource}" ></Image>
Run Code Online (Sandbox Code Playgroud)

将您的依赖项属性实现为Uri:

public static readonly DependencyProperty MyImageSourceProperty =
    DependencyProperty.Register("MyImageSource", 
        typeof(Uri),typeof(UserControl1),
        new FrameworkPropertyMetadata(new PropertyChangedCallback(OnImageSourceChanged)));
Run Code Online (Sandbox Code Playgroud)

在OnImageSourceChanged中:

private static void OnImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    UserControl1 userControl = (UserControl1)sender;

    userControl.someImage.Source = new BitmapImage((Uri) e.NewValue);
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以提供依赖项属性的字符串路径,该属性将自动转换为Uri。

编辑: 在Image中,source属性被实现为ImageSource而不是Uri(抽象类,您的实现,即BitmapSource也从该抽象类派生)。就像我为Uri实现了一个事件一样,它也实现了OnSourceChanged事件。结论是,如果要设置图像源,则必须使用change事件。