WPF 绑定图像源
WPF Binding Image Source
也许是愚蠢的问题,但我不知道了...
我有这样的 ViewModel class:
public class MainWindowsViewModel : INotifyPropertyChanged
{
private ImageSource _img;
public ImageSource StatusImage
{
get { return _img; }
set
{
_img = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName]String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML 中的绑定如下所示:
<Window.DataContext>
<VM:MainWindowsViewModel />
</Window.DataContext>
<Image x:Name="gui_image_status" HorizontalAlignment="Left" Height="26" Margin="144,10,0,0" VerticalAlignment="Top" Width="29" Source="{Binding Path=StatusImage}" />
我这样设置 ImageSource 的内容:
MainWindowsViewModel _view = new MainWindowsViewModel();
var yourImage = new BitmapImage(new Uri(String.Format("Sources/{0}.png", "red"), UriKind.Relative));
_view.StatusImage = yourImage;
但它不起作用。我认为问题出在 NotifyPropertyChanged
,因为我尝试在 set
和 get
中放置制动点。 Get
一开始触发了几次,之后 set
也触发了正确的 ImageSource,但之后 get
就不再触发了。就像从未发生过设置一样。
确实是简单的绑定,我也做过很多次类似的...不知道为什么这次不行。
我没有在你的代码中发现任何问题,但你可以尝试检查一些东西。
- 检查您的图像是否已添加到项目并将图像的构建操作设置为内容(如果较新则复制)。
更新ImageSource前调用Freeze方法防止报错:"Must create DependencySource on same Thread as the DependencyObject"
var yourImage = new BitmapImage(new Uri(String.Format("Sources/{0}.png", "red"), UriKind.Relative));
yourImage.Freeze();
_view.StatusImage = yourImage;
此外,在 WPF 中有一种更简单的绑定图像的方法。您可以使用字符串作为源并将资源路径设置为绑定 属性:
public string StatusImage
{
get { return "/AssemblyName;component/Sources/red.png"; }
}
您正在创建 MainWindowsViewModel class 的两个实例,一个在 XAML 中由
<Window.DataContext>
<VM:MainWindowsViewModel />
</Window.DataContext>
还有一个在
后面的代码中
MainWindowsViewModel _view = new MainWindowsViewModel();
因此您的代码将 属性 设置在与视图绑定到的视图模型实例不同的视图模型实例上。
将您的代码更改为:
var viewModel = (MainWindowsViewModel)DataContext;
viewModel.StatusImage = new BitmapImage(...);
也许是愚蠢的问题,但我不知道了...
我有这样的 ViewModel class:
public class MainWindowsViewModel : INotifyPropertyChanged
{
private ImageSource _img;
public ImageSource StatusImage
{
get { return _img; }
set
{
_img = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName]String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML 中的绑定如下所示:
<Window.DataContext>
<VM:MainWindowsViewModel />
</Window.DataContext>
<Image x:Name="gui_image_status" HorizontalAlignment="Left" Height="26" Margin="144,10,0,0" VerticalAlignment="Top" Width="29" Source="{Binding Path=StatusImage}" />
我这样设置 ImageSource 的内容:
MainWindowsViewModel _view = new MainWindowsViewModel();
var yourImage = new BitmapImage(new Uri(String.Format("Sources/{0}.png", "red"), UriKind.Relative));
_view.StatusImage = yourImage;
但它不起作用。我认为问题出在 NotifyPropertyChanged
,因为我尝试在 set
和 get
中放置制动点。 Get
一开始触发了几次,之后 set
也触发了正确的 ImageSource,但之后 get
就不再触发了。就像从未发生过设置一样。
确实是简单的绑定,我也做过很多次类似的...不知道为什么这次不行。
我没有在你的代码中发现任何问题,但你可以尝试检查一些东西。
- 检查您的图像是否已添加到项目并将图像的构建操作设置为内容(如果较新则复制)。
更新ImageSource前调用Freeze方法防止报错:"Must create DependencySource on same Thread as the DependencyObject"
var yourImage = new BitmapImage(new Uri(String.Format("Sources/{0}.png", "red"), UriKind.Relative)); yourImage.Freeze(); _view.StatusImage = yourImage;
此外,在 WPF 中有一种更简单的绑定图像的方法。您可以使用字符串作为源并将资源路径设置为绑定 属性:
public string StatusImage
{
get { return "/AssemblyName;component/Sources/red.png"; }
}
您正在创建 MainWindowsViewModel class 的两个实例,一个在 XAML 中由
<Window.DataContext>
<VM:MainWindowsViewModel />
</Window.DataContext>
还有一个在
后面的代码中MainWindowsViewModel _view = new MainWindowsViewModel();
因此您的代码将 属性 设置在与视图绑定到的视图模型实例不同的视图模型实例上。
将您的代码更改为:
var viewModel = (MainWindowsViewModel)DataContext;
viewModel.StatusImage = new BitmapImage(...);