【发布时间】:2014-12-30 23:49:36
【问题描述】:
我的应用程序中有一个带有 ObservableCollection 作为 ItemsSource 的 ListBox。 我也有几个类为这个 ItemsSource 提供数据。
public ObservableCollection<Notification> NotificationItems { get; set; }
private object _stocksLock = new object();
我像这样在构造函数中创建集合
this.NotificationItems = new ObservableCollection<Notification>();
System.Windows.Data.BindingOperations.EnableCollectionSynchronization(
this.NotificationItems, _stocksLock);
我正在从多个 dll 程序集中加载为 ListBox 提供数据的模块。在 BackgroundWorker 中调用获取集合的 Notification 数据的方法
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 项目都为 ListBox 提供项目。 这部分工作正常,所以我想接收的数据被加载。 这是我的 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);
}));
}
NotificationPanel 的 XAML 如下所示:
.<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>
当我运行我的应用程序时,它会导致 XamlParseException 对象由另一个线程拥有并且主 ui 线程无法访问它。
谁能帮我解决这个问题?
【问题讨论】:
标签: c# wpf devexpress backgroundworker xamlparseexception