Добавление изображений в StackPanel в WPF - PullRequest
1 голос
/ 14 декабря 2011

У меня есть WPF-приложение, которое ищет новые изображения в базе данных и, если что-то появляется, добавляет изображение в список.Когда возникает это событие, я хочу, чтобы оно добавило изображение в StackPanel.

Сначала я попытался просто вставить изображение, но получил InvalidOperationException, говорящее «Вызывающий поток должен быть STA, потому что многие компоненты пользовательского интерфейсатребовать этого. "и придумал:

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

Это не вызывает каких-либо исключений, но на самом деле ничего не происходит ...

1 Ответ

2 голосов
/ 14 декабря 2011

Что касается моего комментария, вы можете попробовать что-то вроде этого:

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, который автоматически обновит интерфейс с изображениями. Кроме того, использование ItemTemplate означает, что вам не нужно создавать пользовательский интерфейс каждый раз самостоятельно; WPF справится с этим за вас.

См. здесь для получения дополнительной информации об использовании ObservableCollection. Также см. Этот вопрос StackOverflow для объяснения шаблонов контейнера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...