如何创建ImageSource类型的数组?

时间:2013-06-21 15:06:20

标签: c# wpf imagesource

我正在尝试将一组图片设置为我的图像控件。有一个循环将贯穿图片并显示每一个,直到它停在随机图片上。

我的方法:我将图片路径存储在一个字符串中,然后我将其放入一个数组中。在我的循环中,我创建了一个新的ImageSource,并通过显示它的数组项来定义它。我相信我的程序无法工作的原因是ImageSource无法从文件中提取图像并将其设置为图像控制器足够快,然后我才会让线程让图片显示一秒钟。

这是我的代码(假设字符串是正确的路径,我尝试了无数的Thread.Sleep()变量)

此代码运行但它只显示最后一张图片,而不是快速浏览所有图片,然后停在最后一张图片上。

是否会使ImageSource类型的数组保持“手头”的图片更快显示? WPF可以支持获取和设置图像到图像控制器所需的速度吗? 在设置和显示图像之前,我的睡眠线程是否可能执行得太快?

 private void ButtonClick(object sender, RoutedEventArgs e)
 {
  String[] picArray = new String[] { kristen, justin, brandon, sarah, miles, nina };      
  int i = 0;    
  x = rnd.Next(0,5);

        while (i < rnd.Next(10,50)) 
        {
            ImageSource _currentPic = new BitmapImage(new Uri(picArray[x]));                            
            cImage.Source = _currentPic;
            if (x == 5)
                x = 0;
            else
                x++;

            Thread.Sleep(100);
            i++;
        }

    }

循环在数组中的“随机”点停止,以随机化该方法结束的图片。

提前致谢。

2 个答案:

答案 0 :(得分:0)

如果这是一个普通的Windows窗体,您可以使用

this.Refresh() 

在Sleep()之前刷新屏幕(显示当前图像)。

但是,因为它是WPF,所以你必须将该循环产生到一个单独的线程(例如BackgroundWorker)。另一种选择是设置Timer并在每次定时器执行时调用循环的内容。

无论如何,你必须将这个逻辑放到WPF的新线程中。

答案 1 :(得分:0)

您的代码未创建任何新主题。您的UI将冻结,这不是WPF的错。

在UI线程中执行Thread.Sleep()只会使您的应用程序冻结,无论是否WPF。

此外,您不需要WPF中的任何内容。在WPF中,有DataBinding,如果你习惯了一些随机恐龙无用的框架,比如winforms,就不再需要你可能习惯的程序代码中操作UI的所有这些可怕的黑客。

这是在WPF中执行您所描述内容的正确方法:

<Window x:Class="MiscSamples.SlideShowSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SlideShowSample" Height="300" Width="300">
    <Image Source="{Binding ImageSource}"/>
</Window>

代码背后:

public partial class SlideShowSample : Window
{
    public SlideShowSample()
    {
        InitializeComponent();
        DataContext = new SlideShowViewModel();
    }
}

视图模型:

public class SlideShowViewModel:PropertyChangedBase
{
    public const string SourceURL = "http://lorempixel.com/400/200/sports/";

    private string _imageSource;
    public string ImageSource
    {
        get { return _imageSource; }
        set
        {
            _imageSource = value;
            OnPropertyChanged("ImageSource");
        }
    }

    private System.Threading.Timer _slideShowTimer;
    private System.Random _random = new Random();

    public SlideShowViewModel()
    {
        _slideShowTimer = new Timer(x => OnTimerTick(), null, 1000, 3000);
    }

    private void OnTimerTick()
    {
        ImageSource = SourceURL + _random.Next(1, 10).ToString();
    }
}

PropertyChangedBase(MVVM助手类):

public class PropertyChangedBase:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            Application.Current.Dispatcher.BeginInvoke((Action) (() =>
                                                                     {
                                                                         PropertyChangedEventHandler handler = PropertyChanged;
                                                                         if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
                                                                     }));
        }
    }
  • 了解我的代码如何处理任何UI元素。
  • 我的示例从网上下载图像,因此如果您使用本地存储的图像,它应该快得多。
  • 注意UI不会随时冻结。由于实际的图像数据是从网上下载的,因此仍有一点延迟。该下载是在UI线程中执行的,因此您实际上可以改进我的示例以下载异步,但由于您使用的是本地存储的图像,因此无关紧要。