我正在尝试在WPF Window
上包含一个县海豹的图像,并将源绑定到BitmapImage
属性,但是该图像完全不显示。我还想单击图章并使用LeftMouseButtonDown
事件将第一张图像更改为其他七个图像,每次更改之间有两秒钟的延迟。
我尝试了[此StackOverflow帖子]中的技术(How do I bind an Image Source?,但仍然无法显示第一个图像)。
MainWindow.xaml中的图像定义:
<Image x:Name="imag_CountySeal" Margin="0,60,0,80" Grid.Row="0"
Grid.Column="0"
Source="{Binding ImageSource, UpdateSourceTrigger=PropertyChanged,Mode=OneWay}"
MouseLeftButtonDown="Mouse_Down_Seal"
Width="165" Height="165" Visibility="Visible" />
带有ImageSource
属性和PropertyChanged
事件的类定义:
public class CountySeals : INotifyPropertyChanged
{
private BitmapImage _ImageSource;
public BitmapImage ImageSource
{
get { return _ImageSource; }
set
{
_ImageSource = value;
OnPropertyChanged(new PropertyChangedEventArgs("ImageSource"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
}
在MainWindow.xaml.cs
开头为第一张图片设置ImageSource
的逻辑:
public partial class MainWindow : Window
{
CountySeals seals;
public MainWindow()
{
InitializeComponent();
seals = new CountySeals();
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_l transparent.png", UriKind.Absolute));
SizeChanged += new SizeChangedEventHandler(Window_SizeChanged);
StateChanged += new EventHandler(Window_StateChanged);
LocationChanged += new EventHandler(Window_LocationChanged);
Mouse_Down_Seal
中的 MainWindow.xaml.cs
代码:
private void Mouse_Down_Seal(object sender, MouseButtonEventArgs e)
{
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_2 transparent.png", UriKind.Absolute));
Thread.Sleep(2000);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_3 transparent.png", UriKind.Absolute));
Thread.Sleep(2000);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_4 transparent.png", UriKind.Absolute));
Thread.Sleep(2000);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_5 transparent.png", UriKind.Absolute));
Thread.Sleep(2000);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_6 transparent.png", UriKind.Absolute));
Thread.Sleep(2000);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_7 transparent.png", UriKind.Absolute));
Thread.Sleep(2000);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_8 transparent.png", UriKind.Absolute));
}
如何为Binding
连接ImageSource
?
答案 0 :(得分:1)
您需要将图章设置为MainWindow DataContext:
public MainWindow()
{
InitializeComponent();
seals = new CountySeals();
this.DataContext = seals; // <---------
... etc ...
更新:您的位图不显示的问题是一个完全独立的问题。您的鼠标处理程序在GUI线程上被调用,但是您随后使用Task.Sleep
命令将该线程绑定起来,因此它永远没有机会更新映像。实际上,您会发现整个过程将冻结整个应用程序。您需要分配ImageSource
并在一个单独的线程中进行睡眠等操作,而在C#中正确的方法是使用Tasks(很少有例外,您永远不要在其中调用Thread.Sleep()
C#)。您还需要添加代码以检查任务是否已在运行,然后如果需要则先将其取消。这样的事情应该可以解决问题:
private Task DisplayTask;
private CancellationTokenSource CancelSource;
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
// cancel any existing task and wait for it to finish
if (this.CancelSource != null)
{
this.CancelSource.Cancel();
try
{
this.DisplayTask.Wait(this.CancelSource.Token);
}
catch (OperationCanceledException)
{
// catches the expected exception here
}
}
// start a new task
this.CancelSource = new CancellationTokenSource();
this.DisplayTask = Task.Run(DisplayImages);
}
private async Task DisplayImages()
{
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_2 transparent.png", UriKind.Absolute));
await Task.Delay(TimeSpan.FromSeconds(2), this.CancelSource.Token);
seals.ImageSource = new BitmapImage(new Uri(@"C:\Users\billw\Documents\Visual Studio 2015\Projects\Images\seal_3 transparent.png", UriKind.Absolute));
await Task.Delay(TimeSpan.FromSeconds(2), this.CancelSource.Token);
... etc ...
}