在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());
        }
    }
}

这不会抛出任何类型的异常,但实际上什么也没发生…

在WPF中添加图像到StackPanel

参考我的评论,你可以尝试这样做:

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问题。