在WPF中添加图像到StackPanel
本文关键字:StackPanel 图像 添加 WPF | 更新日期: 2023-09-27 18:17:54
我有一个wpf应用程序,它正在数据库中寻找新图像,如果出现了什么,它将图像添加到列表中。当该事件被引发时,我希望它将图像添加到StackPanel中。
首先,我尝试只是插入图像,但得到一个InvalidOperationException
说"调用线程必须是STA,因为许多UI组件需要这个",并提出:
public void Instance_GraphicChanged(object sender, PropertyChangedEventArgs e)
{
foreach (Model.Graphic item in Model.IncomingCall.Instance.Graphics)
{
if(!_strings.Contains(item.ImageId.ToString()))
{
Thread thread = new Thread( new ThreadStart(
delegate()
{
//sp_images StackPanel for Images
sp_images.Dispatcher.Invoke(
DispatcherPriority.Normal, new Action(
delegate()
{
Image img = new Image();
img.Source = item.ImageObj; //ImageObj returns a BitmapImage
sp_images.Children.Add(img);
}
));
}
));
_strings.Add(item.ImageId.ToString());
}
}
}
这不会抛出任何类型的异常,但实际上什么也没发生…
参考我的评论,你可以尝试这样做:
XAML
<!-- ... Other XAML Code ... -->
<ItemsControl x:Name="sp_images">
<ItemsControl.ItemsPanel>
<StackPanel Orientation="Horizontal" />
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
代码后面
private readonly HashSet<string> mImageIds = new HashSet<string>();
private readonly ObservableCollection<BitmapImage> mImages = new ObservableCollection<BitmapImage>();
// ... Inside the constructor
{
InitializeComponent();
sp_images.ItemsSource = mImages;
}
public void Instance_GraphicChanged(object sender, PropertyChangedEventArgs e)
{
foreach (Model.Graphic item in Model.IncomingCall.Instance.Graphics)
{
// Have we already seen the image
if (mImageIds.Add(item.ImageId.ToString()))
{
// We've not seen the image yet, so add it to the collection
// Note: We must invoke this on the Dispatcher thread.
this.Dispatcher.BeginInvoke((Action)delegate()
{
mImages.Add(item.ImageObj);
});
}
}
}
这将绕过之前可能遇到的任何跨线程异常。它还应该允许您轻松地向ObservableCollection
添加新图像,这将自动使用图像更新UI。此外,使用ItemTemplate
意味着你不必每次都自己构建UI;WPF将为您处理此问题。
请参阅此处获取有关使用ObservableCollection
的更多信息。另外,关于容器模板的解释,请参考StackOverflow问题。