Reputation: 4179
To describe my problem i have created a small application. At first the Usercontrol:
<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>
second the 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>
third the code behind the usercontrol
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();
}
}
}
I know that the Type BitMapImage (of the DP) doesnt work in this way, but i want to know how to implement this feature in a clean, typesave way. I want to reach the same behaviour like the original Image.Source implementation.
thanks in advance, Scott
Upvotes: 4
Views: 7292
Reputation: 1
make MyImageSource property of type string not BitmapImage
public static readonly DependencyProperty MyImageSourceProperty =
DependencyProperty.Register("MyImageSource",
typeof(string),typeof(UserControl1),
new FrameworkPropertyMetadata(OnImageSourcePathChanged));
public string MyImageSource
{
get { return (BitmapImage)GetValue(MyImageSourceProperty); }
set { SetValue(MyImageSourceProperty, value); }
}
private static void OnImageSourcePathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((UserControl1)d).MyImageSource.Source = new BitmapImage(new Uri(e.NewValue as string));
}
usage:
<WpfApplication10:UserControl1 MyImageSource="c:\test.png" > </WpfApplication10:UserControl1>
Upvotes: 0
Reputation: 14608
In your control, name your Image as:
<Image x:Name="someImage" Source="{Binding Path=MyImageSource}" ></Image>
Implement your dependency property as Uri:
public static readonly DependencyProperty MyImageSourceProperty =
DependencyProperty.Register("MyImageSource",
typeof(Uri),typeof(UserControl1),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnImageSourceChanged)));
And in OnImageSourceChanged:
private static void OnImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
UserControl1 userControl = (UserControl1)sender;
userControl.someImage.Source = new BitmapImage((Uri) e.NewValue);
}
This way, you can supply a string path to the dependency property which will be converted to Uri automatically.
EDIT: In Image, the source property is implemented as ImageSource instead of Uri (an abstract class, from which your implementation, i.e. BitmapSource, also derives). It also implements a OnSourceChanged event just like I have implemented one for Uri. The conclusion is, that you will have to use a change event if you want to set the source of an image.
Upvotes: 5
Reputation: 2524
You need to create a converter. since your DP defined to be Bitmapimage and in XAML you bind it to string.
Maybe you can find suitable converter here. http://www.codeplex.com/wpfconverters
or try to google "WPF converters"
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
return new BitmapImage(new Uri((string)value));
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and let your MyImageSource be typeof string. Then you can use converter inside UserControl definition.
Upvotes: 1