【问题标题】:How do I create an array of type ImageSource?如何创建 ImageSource 类型的数组?
【发布时间】:2013-06-21 15:06:19
【问题描述】:

我正在尝试制作一组​​图片以设置为我的图像控件。有一个循环将遍历图片并显示一秒钟,直到它在随机图片上停止。

我的方法:我将图片路径存储在一个字符串中,然后将其放入一个数组中。在我的循环中,我创建了一个新的 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++;
        }

    }

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

提前谢谢。

【问题讨论】:

  • ImageSource[],这肯定会更快,这取决于您如何存储它们,如果您只是在这种方法中将它们保存在本地,那么这将花费更长的时间
  • 与您的问题无关,但您似乎在 UI 线程上执行了一些长时间的操作,尤其是在使用 Thread.Sleep() 调用时。您可能需要考虑改变这一点。
  • 我尝试使用 ImageSource[] 但它不允许我创建该类型的数组。关于 thread.sleep(),我并没有考虑太多。使用计时器会更有效吗?
  • 也许this 有帮助。

标签: c# wpf imagesource


【解决方案1】:

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

this.Refresh() 

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

但是,由于它是 WPF,因此您必须将该循环生成到单独的线程中(例如 BackgroundWorker)。另一种选择是设置Timer,并在每次计时器执行时调用循环的内容。

无论如何,您必须将该逻辑放到 WPF 的新线程中。

【讨论】:

  • WPF Window 类中没有这样的方法。我猜你在 WinForms 中指的是Control.Refresh
  • 我喜欢刷新的想法,以确保它是当前正在显示的图片。当我的程序具有在图片循环中运行时可以使用的功能时,我最终会添加一个新线程。
  • 呸!是的,那是旧的 Windows 窗体,而不是 WPF。进入 WPF,问题变得更加复杂。 (正在修改)
  • @muffinMan。你真的应该用计时器来做,如this answer(或许多其他人)所示。在调度程序线程中使用 Thread.Sleep 循环会杀死你的 UI。
【解决方案2】:

您的代码没有创建任何新线程。您的 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 元素。
  • 我的示例从 Web 下载图像,因此如果您使用本地存储的图像,它应该会快得多。
  • 注意 UI 不会在任何时候冻结。仍然有一点延迟,因为实际的图像数据是从网上下载的。该下载是在 UI 线程中执行的,因此您实际上可以改进我的示例以异步下载,但由于您使用的是本地存储的图像,所以没关系。

【讨论】:

  • 感谢您向我展示了如此详尽的样本,并解决了我使用恐龙方法引起的许多问题。我刚接到一个工作任务,所以我会在完成后立即测试代码。我还没有真正进入官方视图模型,并且可能需要一些简单的帮助来澄清类所属的位置或如何修改它以满足我的确切需求。再次感谢
  • 我刚刚测试了这段代码。我对公共 SlideShowViewModel() 有疑问。更具体地说,它表示计时器不会采用 4 个参数。
  • @muffinMan TimerSystem.Threading.Timer,请检查您的使用情况。
猜你喜欢
  • 2012-05-30
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
相关资源
最近更新 更多