如何将画布中的图像链接到对象

时间:2016-11-28 15:23:37

标签: c# wpf canvas

我有以下课程:

class Sapo
{
   private Image imgSapo;

   public int IdSapo { get; }

   public Sapo(int id)
   {
       imgSapo = new Image();
       IdSapo = id;
   }

   public Image show
   {
      get 
      {
        imgSapo.Source = new BitmapImage(new Uri("pack://application:,,,/Imagens/sapo.png", UriKind.Absolute));
        imgSapo.Width = 56;
        imgSapo.Height = 56;

        return imgSapo;
      }
  }
}

我有一个方法,我创建一个线程传递类Sapo的每个对象的实例:

public void CriarSapos()
{
   Thread th;

   int sapos = int.Parse(txt_sapos.Text);

   Sapo[] arraySapos = new Sapo[sapos];

   for (int i = 0; i < sapos; i++)
   {
       th = new Thread(new ParameterizedThreadStart(ThreadImageSapo));
       th.SetApartmentState(ApartmentState.STA);
       th.IsBackground = true;
       arraySapos[i] = new Sapo(th.ManagedThreadId);
       th.Start(arraySapos[i]);
   }
}

负责在画布上插入图像的方法:

public void ThreadImageSapo(object obj)
{
   Dispatcher.Invoke(() =>
   {
       Sapo _sapo = (Sapo)obj;

       double max_x = _canvas.ActualWidth - _sapo.show.Width;
       double max_y = _canvas.ActualHeight - _sapo.show.Height;

       Canvas.SetLeft(_sapo.show, rnd.NextDouble() * max_x);
       Canvas.SetTop(_sapo.show, rnd.NextDouble() * max_y);

       _canvas.Children.Add(_sapo.show);

   });
}

我的目标是我想检查画布中图像的碰撞并销毁该图像对象所包含的线程

我的问题是:如何获取画布图像的相应对象?

1 个答案:

答案 0 :(得分:0)

首先,您通常不应在后面的代码中创建UI元素,尤其是在非UI线程中。更改Sapo类,使其在属性中保存BitmapImage,而不是Image控件。另外,请确保在BitmapImage上调用Freeze()以使其可跨线程访问。

public class Sapo
{
    public int IdSapo { get; private set; }
    public double Width { get; private set; }
    public double Height { get; private set; }
    public BitmapImage Image { get; private set; }

    public Sapo(int id)
    {
        IdSapo = id;
        Width = 56;
        Height = 56;
        Image = new BitmapImage(new Uri("pack://application:,,,/Imagens/sapo.png"));
        Image.Freeze();
    }
}

现在,当您将图像添加到Canvas时,创建一个Image控件并像这样分配BitmapImage:

Dispatcher.Invoke(() =>
{
    var sapo = (Sapo)obj;
    var image = new Image
    {
        Source = sapo.Image,
        Width = sapo.Width,
        Height = sapo.Height
    };

    double maxX = _canvas.ActualWidth - image.Width;
    double maxY = _canvas.ActualHeight - image.Height;

    Canvas.SetLeft(image, rnd.NextDouble() * maxX);
    Canvas.SetTop(image, rnd.NextDouble() * maxY);

    _canvas.Children.Add(image);
});

这仍然会在代码后面创建一个Image控件,但是在UI线程中。更好的解决方案可能是使用带有Canvas的ItemsControl作为ItemsPanel。