我正在尝试将一组图片设置为我的图像控件。有一个循环将贯穿图片并显示每一个,直到它停在随机图片上。
我的方法:我将图片路径存储在一个字符串中,然后我将其放入一个数组中。在我的循环中,我创建了一个新的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++;
}
}
循环在数组中的“随机”点停止,以随机化该方法结束的图片。
提前致谢。
答案 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));
}));
}
}