C# 将图像Url数组绑定到自定义图像控件属性

C# 将图像Url数组绑定到自定义图像控件属性,c#,wpf,image,xaml,custom-controls,C#,Wpf,Image,Xaml,Custom Controls,如果列表中有多个图像,我需要在x时间后更改鼠标上的图像 为了实现这一点,我开发了一个自定义图像控件,我的控件有两个属性,基本上是MainImageSource,它是BitmapImage,ImageUrl,它是IList 现在我要做的是,onmouseenter启动一个计时器,并在计时器已过并重置image onmouseleave事件后,将mainmagesource更改为列表中的下一个图像(如果有) 一切正常,比如当我设置ImageURL时,它会按预期设置图像 现在我需要在ListBox中使

如果列表中有多个图像,我需要在x时间后更改鼠标上的图像

为了实现这一点,我开发了一个自定义图像控件,我的控件有两个属性,基本上是MainImageSource,它是BitmapImage,ImageUrl,它是IList

现在我要做的是,onmouseenter启动一个计时器,并在计时器已过并重置image onmouseleave事件后,将
mainmagesource
更改为列表中的下一个图像(如果有)

一切正常,比如当我设置ImageURL时,它会按预期设置图像

现在我需要在ListBox中使用这个控件,它是绑定到类型为
FileItem
(自定义类)的ObservableCollection的数据。现在在listbox中,我需要设置该数组,所以我要做的是,在
FileItem
中添加一个名为
imageURL
的属性,类型为
string[]
。 在xaml中,我使用以下方法绑定数据

<local:MBImage ImageUrl="{Binding ImageUrls}"  Source="{Binding MainImageSource}" />
这表明它在MBImage中查找ImageURL,而不是ObservableCollection类型的listbox itemsource

MBImage.cs

class MBImage : Image, INotifyPropertyChanged
{
    private List<BitmapImage> bmpImages = new List<BitmapImage>();
    private Timer imgChangeTimer = new Timer(1000);
    private int curImage = 0;

    BitmapImage _MainImageSource = null;
    public event PropertyChangedEventHandler PropertyChanged;

    public static readonly DependencyProperty ImageUrlProperty = DependencyProperty.Register("ImageUrl", typeof(IList<string>), typeof(MBImage));

    public IList<string> ImageUrl
    {
        get { return (IList<string>)this.GetValue(ImageUrlProperty); }
        set
        {                
            this.SetValue(ImageUrlProperty, value);
            DownloadImages();
        }
    }

    public MBImage()
    {
        imgChangeTimer.Elapsed += new ElapsedEventHandler(imgChangeElapsed);
        DataContext = this;
    }

    public BitmapImage MainImageSource
    {
        get
        {
            return _MainImageSource;
        }
        set
        {
            _MainImageSource = value;
            OnPropertyChanged("MainImageSource");
        }
    }

    private void DownloadImages()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += (s, e) =>
        {
            List<ImageDownloadArgs> argList = new List<ImageDownloadArgs>();

            int index = (int)e.Argument;
            int count = 1;
            if (index == -1)
            {
                count = ImageUrl.Count();
                index = 1;
            }

            for (int i = index; i < count; i++)
            {
                ImageDownloadArgs args = new ImageDownloadArgs();
                args.Index = i;


                Uri uri = new Uri(ImageUrl[i], UriKind.Absolute);

                using (WebClient webClient = new WebClient())
                {
                    webClient.Proxy = null;  
                    webClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
                    try
                    {
                        byte[] imageBytes = null;

                        imageBytes = webClient.DownloadData(uri);

                        if (imageBytes == null)
                        {
                            e.Result = null;
                            return;
                        }
                        MemoryStream imageStream = new MemoryStream(imageBytes);
                        args.Img = new BitmapImage();

                        args.Img.BeginInit();
                        args.Img.StreamSource = imageStream;
                        args.Img.CacheOption = BitmapCacheOption.OnLoad;
                        args.Img.EndInit();

                        args.Img.Freeze();
                        imageStream.Close();

                        argList.Add(args);

                    }
                    catch (WebException)
                    {                
                        //argList.Add(args);
                    }
                }
            }
            e.Result = argList;
        };

        worker.RunWorkerCompleted += (s, e) =>
        {
            List<ImageDownloadArgs> argList = e.Result as List<ImageDownloadArgs>;
            bool shouldDownloadRest = false;
            foreach (ImageDownloadArgs args in argList)
            {
                if (args != null)
                {
                    if (args.Index == 0)
                    {
                        MainImageSource = args.Img;
                        bmpImages.Add(args.Img);
                        shouldDownloadRest = true;
                    }
                    else
                    {
                        bmpImages.Add(args.Img);
                    }
                }
            }

            worker.Dispose();
            if (shouldDownloadRest)
                worker.RunWorkerAsync(-1);

        };

        worker.RunWorkerAsync(0);

    }

    private void imgChangeElapsed(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Time out");
        MainImageSource = bmpImages[++curImage % bmpImages.Count()];

    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        imgChangeTimer.Start();
    }

    protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
    {
        imgChangeTimer.Stop();
        MainImageSource = bmpImages[0];
        curImage = 0;

    }
}
class MBImage:Image,INotifyPropertyChanged
{
私有列表bmpImages=新列表();
专用定时器imgChangeTimer=新定时器(1000);
私有int-curImage=0;
BitmapImage _MainImageSource=null;
公共事件属性更改事件处理程序属性更改;
public static readonly dependencProperty ImageUrlProperty=dependencProperty.Register(“ImageUrl”、typeof(IList)、typeof(MBImage));
公共IList ImageUrl
{
获取{return(IList)this.GetValue(ImageUrlProperty);}
设置
{                
this.SetValue(ImageUrlProperty,value);
下载图像();
}
}
公共MBImage()
{
imgChangeTimer.Appeased+=新的ElapsedEventHandler(imgChangeTimer);
DataContext=this;
}
公共位图图像MainImageSource
{
得到
{
返回MainImageSource;
}
设置
{
_MainImageSource=值;
OnPropertyChanged(“MainImageSource”);
}
}
私有void下载图像()
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=(s,e)=>
{
List argList=新列表();
int index=(int)e.参数;
整数计数=1;
如果(索引==-1)
{
count=ImageUrl.count();
指数=1;
}
for(int i=索引;i
{
列表argList=e。结果为列表;
bool shouldDownloadRest=false;
foreach(ImageDownloadArgs args args argList中的args)
{
如果(args!=null)
{
如果(args.Index==0)
{
MainImageSource=args.Img;
bmpImages.Add(args.Img);
shouldDownloadRest=true;
}
其他的
{
bmpImages.Add(args.Img);
}
}
}
worker.Dispose();
如果(应该下载REST)
worker.RunWorkerAsync(-1);
};
worker.RunWorkerAsync(0);
}
私有无效IMGChangePassed(对象发送方,ElapsedEventArgs e)
{
控制台写入线(“超时”);
MainImageSource=bmpImages[++curImages%bmpImages.Count()];
}
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
MouseCenter上受保护的覆盖无效(System.Windows.Input.MouseEventArgs e)
{
imgChangeTimer.Start();
}
MouseLeave上的受保护覆盖无效(System.Windows.Input.MouseEventArgs e)
{
imgChangeTimer.Stop();
MainImageSource=bmp图像[0];
curImage=0;
}
}

问题在于,您正在
将MBImage的DataContext设置为其自身
在其构造函数中
DataContext=this,您不应该这样做。这就是当您执行
ImageUrl=“{Binding ImageUrl}”

删除
DataContext=this
class MBImage : Image, INotifyPropertyChanged
{
    private List<BitmapImage> bmpImages = new List<BitmapImage>();
    private Timer imgChangeTimer = new Timer(1000);
    private int curImage = 0;

    BitmapImage _MainImageSource = null;
    public event PropertyChangedEventHandler PropertyChanged;

    public static readonly DependencyProperty ImageUrlProperty = DependencyProperty.Register("ImageUrl", typeof(IList<string>), typeof(MBImage));

    public IList<string> ImageUrl
    {
        get { return (IList<string>)this.GetValue(ImageUrlProperty); }
        set
        {                
            this.SetValue(ImageUrlProperty, value);
            DownloadImages();
        }
    }

    public MBImage()
    {
        imgChangeTimer.Elapsed += new ElapsedEventHandler(imgChangeElapsed);
        DataContext = this;
    }

    public BitmapImage MainImageSource
    {
        get
        {
            return _MainImageSource;
        }
        set
        {
            _MainImageSource = value;
            OnPropertyChanged("MainImageSource");
        }
    }

    private void DownloadImages()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += (s, e) =>
        {
            List<ImageDownloadArgs> argList = new List<ImageDownloadArgs>();

            int index = (int)e.Argument;
            int count = 1;
            if (index == -1)
            {
                count = ImageUrl.Count();
                index = 1;
            }

            for (int i = index; i < count; i++)
            {
                ImageDownloadArgs args = new ImageDownloadArgs();
                args.Index = i;


                Uri uri = new Uri(ImageUrl[i], UriKind.Absolute);

                using (WebClient webClient = new WebClient())
                {
                    webClient.Proxy = null;  
                    webClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
                    try
                    {
                        byte[] imageBytes = null;

                        imageBytes = webClient.DownloadData(uri);

                        if (imageBytes == null)
                        {
                            e.Result = null;
                            return;
                        }
                        MemoryStream imageStream = new MemoryStream(imageBytes);
                        args.Img = new BitmapImage();

                        args.Img.BeginInit();
                        args.Img.StreamSource = imageStream;
                        args.Img.CacheOption = BitmapCacheOption.OnLoad;
                        args.Img.EndInit();

                        args.Img.Freeze();
                        imageStream.Close();

                        argList.Add(args);

                    }
                    catch (WebException)
                    {                
                        //argList.Add(args);
                    }
                }
            }
            e.Result = argList;
        };

        worker.RunWorkerCompleted += (s, e) =>
        {
            List<ImageDownloadArgs> argList = e.Result as List<ImageDownloadArgs>;
            bool shouldDownloadRest = false;
            foreach (ImageDownloadArgs args in argList)
            {
                if (args != null)
                {
                    if (args.Index == 0)
                    {
                        MainImageSource = args.Img;
                        bmpImages.Add(args.Img);
                        shouldDownloadRest = true;
                    }
                    else
                    {
                        bmpImages.Add(args.Img);
                    }
                }
            }

            worker.Dispose();
            if (shouldDownloadRest)
                worker.RunWorkerAsync(-1);

        };

        worker.RunWorkerAsync(0);

    }

    private void imgChangeElapsed(object sender, ElapsedEventArgs e)
    {
        Console.WriteLine("Time out");
        MainImageSource = bmpImages[++curImage % bmpImages.Count()];

    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        imgChangeTimer.Start();
    }

    protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
    {
        imgChangeTimer.Stop();
        MainImageSource = bmpImages[0];
        curImage = 0;

    }
}
public static readonly DependencyProperty ImageUrlProperty = DependencyProperty.Register("ImageUrl", typeof(IList<string>), typeof(MBImage), new FrameworkPropertyMetadata(null, ImageUrlsChanged));