将图像Url数组绑定到自定义图像控制属性

时间:2013-09-26 02:44:48

标签: c# wpf image xaml custom-controls

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

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

现在我在这里做的是onmouseenter启动一个计时器并在计时器hass过去并重置图像onmouseleave事件后将MainImageSource更改为列表中的下一个图像(如果有的话)。

一切正常,就像我设置图像时一样,按照预期设置图像。

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

<local:MBImage ImageUrl="{Binding ImageUrls}"  Source="{Binding MainImageSource}" />

MBImage的ImageUrl从未设置过。

所以现在有两件事

  1. 如何ImageUrls FileItem ImageUrl MBImage Source="{Binding MainImageSource}"
  2. 我怎样才能摆脱MBImage。因为它在Source内部使用。如果我不使用MainImageSource属性,即使我更新了MBImage 'ImageUrls' property not found on 'object' ''MBImage' (Name='')' ,它也不会改变图像。
  3. 添加到一切是有更好的方法来实现我的主要目标,即在悬停时显示多个图像。如果我找到比这更好的方法并且使用更多WPF的优势,我愿意重写所有内容。

    被修改

    这是错误

    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;
    
        }
    }
    

    显示它在MBImage中寻找ImageUrls而不是ObservableCollection类型的listbox itemsource。

    MBImage.cs

    {{1}}

1 个答案:

答案 0 :(得分:1)

问题是你的构造函数Setting the DataContext of MBImage to itselfDataContext = this;,你不应该这样做。这就是你在ImageUrl="{Binding ImageUrls}"

时搜索属性的原因

删除DataContext = this;此行,因为它不是必需的。

另外我看到你在属性设置器中做了一些工作,这不会从Xaml绑定调用,因为wpf内部调用GetValue和SetValue函数..如果你想对属性值集进行一些注册,请注册ValueChanged在定义它时在依赖项属性元数据中回调,并在valuechanged处理程序

中执行此操作
public static readonly DependencyProperty ImageUrlProperty = DependencyProperty.Register("ImageUrl", typeof(IList<string>), typeof(MBImage), new FrameworkPropertyMetadata(null, ImageUrlsChanged));