如何连接ImageSource的绑定?

时间:2019-01-07 00:01:39

标签: c# wpf image xaml data-binding

我正在尝试在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

1 个答案:

答案 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 ...
}