ObservableCollection이있는 ListBox에 내 응용 프로그램의 ItemsSource가 있습니다. 또한이 ItemsSource에 대한 데이터를 제공하는 serveral 클래스가 있습니다.ItemsWork를 BackgroundWorker에서 수정하면 예외가 발생합니다.
public ObservableCollection<Notification> NotificationItems { get; set; }
private object _stocksLock = new object();
은 내가 serveral DLL 어셈블리에서리스트 박스에 대한 데이터를 제공하는 모듈을로드하고 그
this.NotificationItems = new ObservableCollection<Notification>();
System.Windows.Data.BindingOperations.EnableCollectionSynchronization(
this.NotificationItems, _stocksLock);
처럼 내 생성자 내 컬렉션을 만들 수 있습니다. 컬렉션은 BackgroundWorker에
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += GetPluginModuleNotifications;
List<IModul> Modules = new List<IModul>();
//[...]
foreach (IModul PluginModul in AssemblyList)
{
//[...]
Modules.Add(PluginModul);
//[...]
}
this.Notifications.ItemsSource = this.NotificationItems;
object[] Parameter = new object[] { Modules, this.ComponentFactory,
this.MyListBox};
//-->Edited
worker.WorkerReportsProgress = true;
worker.ProgressChanged += OnProgressChanged;
//<--Edited
worker.RunWorkerAsync(Parameter);
//...
//-->EDITED
private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
Notification toAdd = (Notification)e.UserState;
this.NotificationItems.Add(toAdd);
}
//<--EDITED
내에서 호출되는 방법은 내가 목록 상자에 대한 항목을 제공하기 위해 IModul 각 항목을 원하는 알림 데이터를 얻을 수 있습니다. 이 부분은 잘 작동하므로 수신 할 데이터가로드됩니다. 내 응용 프로그램을 실행하고 때이 객체가 다른 스레드가 소유하고 있음을 XamlParseException의 원인이됩니다
.<dx:DXListBox x:Name="Notifications" VerticalAlignment="Stretch" BorderBrush="Transparent" MouseDoubleClick="NotificationGotoSource" ItemsSource="{Binding NotificationItems}">
<dx:DXListBox.ItemTemplate>
<DataTemplate DataType="{x:Type cbcore:Notification}">
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="38" />
<ColumnDefinition Width="*" MinWidth="157"/>
<ColumnDefinition Width="15" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageSource}" Grid.Column="0" Width="32" Height="32" VerticalAlignment="Top" HorizontalAlignment="Left" />
<StackPanel Orientation="Vertical" Grid.Column="1">
<Label FontWeight="Bold" FontSize="10" MaxHeight="25" MaxWidth="150">
<TextBlock Text="{Binding Headline}" TextWrapping="Wrap" />
</Label>
<Label FontWeight="Normal" FontSize="9" MaxHeight="100" MaxWidth="150">
<TextBlock Text="{Binding Note}" TextWrapping="Wrap" />
</Label>
</StackPanel>
<Label Cursor="Hand" Padding="0" Margin="0" MouseLeftButtonUp="Notification_RemoveSelected" Grid.Column="2"
OverridesDefaultStyle="True" BorderBrush="Black" Background="Transparent"
FontSize="8" FontWeight="Bold" VerticalAlignment="Top" HorizontalAlignment="Right">
<TextBlock Foreground="Red" TextAlignment="Center">X</TextBlock>
</Label>
</Grid>
</StackPanel>
</DataTemplate>
</dx:DXListBox.ItemTemplate>
</dx:DXListBox>
: 다음은 NotificationPanel의 XAML은 다음과 같습니다 내 BackgroundWorker.DoWork 이벤트
private void GetPluginModuleNotifications(object sender, DoWorkEventArgs e)
{
object[] args = e.Argument as object[];
if (args == null || args.Length != 3) return;
List<IModul> Module = args[0] as List<IModul>;
IComponentFactory Factory = args[1] as IComponentFactory;
// DXListBox lb = args[2] as DXListBox;
if (Module == null || Factory == null) return;
foreach (IModul Modul in Module)
{
Notification[] res = Modul.GetImportantNotifications(Factory);
if (res == null || res.Length == 0) continue;
foreach (Notification notif in res)
{
//-->EDITED
(sender as BackgroundWorker).ReportProgress(1, notif);
System.Threading.Thread.Sleep(100);
//this.ReceiveNotification(notif);
//<--EDITED
}
}
}
private void ReceiveNotification(Notification obj)
{
if (obj == null) return;
Dispatcher.BeginInvoke(new Action(() =>
{
this.NotificationItems.Add(obj);
if (this.NotificationPanel.Width.Value == 0)
this.NotificationPanel.Width = new GridLength(NOTIFICATION_BAR_WIDTH);
}));
}
입니다 메인 UI 스레드가 액세스 할 수 없습니다.
누구든지 저 문제를 해결할 수 있습니까?
이전에도이 방법을 시도했지만 예외가 발생합니다. – DaKirsche
수정 된 코드 게시 – Sievajet
스 니펫을 추가했습니다. 나는 그것이 내가 수정 한 것 뿐이라고 생각한다. //-> EDITED 코드 블록으로 표시 – DaKirsche