2016-09-06 1 views
-1

Я хочу изменить ListBox ItemsSource без замораживания пользовательского интерфейса. Для этой задачи я написал код, который вы видите ниже;Изменить Listbox ItemsSource с разными Thread

Когда пользователь нажимает кнопку

Thread th = new Thread(DisplayFilesAsync); 
th.Start(new object[] { FolderPath, fdv.FileType }); 

Асинхронный метод

private void DisplayFilesAsync(object param) 
{ 
    object[] args = param as object[]; 
    string searchText = Convert.ToString(args[0]); 
    FileType type = (FileType)args[1]; 
    IEnumerable<FileListItem> list = uDirectoryHelper.GetFileFromFolder(searchText, type); 
    Dispatcher.BeginInvoke(new Action<IEnumerable<FileListItem>>(DisplayFiles), DispatcherPriority.Background, new object[] { list }); 
} 

изменить ItemsSource

private void DisplayFiles(IEnumerable<FileListItem> fileList) 
{ 
    lstFiles.ItemsSource = fileList; 
} 

В последнем методе, если я меняю непосредственно ItemSource из ListBox, программа не разрушается, но когда программа переходит к закрытой фигурных скобках метода является разбить и бросаться должны создать DependencySource на то же самое Thread as the DependencyObject исключение.

если я изменил это; он снова разбивается на закрытые фигурные скобки, а не на метод ADD и генерирует одно и то же исключение.

private void DisplayFiles(IEnumerable<FileListItem> fileList) 
{ 
    foreach (FileListItem item in fileList) 
    { 
     lstFiles.Items.Add(item); 
    } 
} 

Но если я так изменил код, он отлично работает и добавит элементы в мой список.

foreach (FileListItem item in fileList) 
{ 
    lstFiles.Items.Add("EXAMPLE"); 
} 

Я действительно не понимаю своих недостающих. Почему я могу добавить к некоторой строке, но я не могу добавить в свой класс FileListItem. Что мне не хватает? Я пробовал много другого кода, но он всегда ломается на закрытых фигурных скобках, а не на линии слияния.

Мне действительно нужно помочь. Спасибо за ответы. Имейте хороший день, добрые дела.

+0

Этот вопрос может помочь вам: http: // stackoverflow.com/questions/1862590/how-to-update-gui-with-backgroundworker – EJoshuaS

+0

К сожалению, с фоновым работником у меня тоже такая же ошибка. –

+0

Как выглядит ваш класс FileListItem? Это DependcyObject? Если это так, возможно, вам придется создать его в потоке пользовательского интерфейса. Если у вас проблемы с точкой останова, возможно, VisualStudio не запускает последнюю версию вашего кода ... попробуйте очистить проект и перестроить. Возможно, вам захочется проверить, что файлы на самом деле исчезли после очистки и перед восстановлением. –

ответ

0

Ваш класс FileListItem имеет свойство типа ImageSource

public ImageSource ItemImage { get; set; } 

Хотя вы не показывают, что в вашем вопросе, вы, конечно, присвоить значение этого свойства в вашем GetFileFromFolder способом, например, как

fileList.ItemImage = new BitmapImage(new Uri(...)); 

Если только в BitmapImage не замерзла в фоновом потоке, не могут быть доступны в потоке пользовательского интерфейса, следовательно, вы получите это исключение.

Убедитесь, что вы вызываете метод Freeze() на BitmapImage после того, как он загрузил растровое изображение. Обратите внимание, что вы не можете выполнять асинхронную загрузку растрового изображения (например, с помощью удаленного URI) в этой ситуации. Если битовая карта загружается из локального файла, сделать что-то вроде этого:

var bitmap = new BitmapImage(); 

using (var stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read)) 
{ 
    bitmap.BeginInit(); 
    bitmap.CacheOption = BitmapCacheOption.OnLoad; 
    bitmap.StreamSource = stream; 
    bitmap.EndInit(); 
    bitmap.Freeze();   
} 

fileList.ItemImage = bitmap; 

Или, вместо BitmapImage, используйте BitmapFrame.Create() метод, который уже возвращает замороженные BitmapFrame (другой подкласс ImageSource).

using (var stream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read)) 
{ 
    fileList.ItemImage = BitmapFrame.Create(
     stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 
}