【发布时间】:2014-12-30 21:53:53
【问题描述】:
我有两个线程 - 我们将它们命名为 Calc 线程和 UI 线程。在 Calc 线程中,我刷新了一个 ObservableCollection。我还有一个 ObservableCollection 的 CollectionCHanged 事件的处理程序。据我所知,处理程序在引发 CollectionChanged 事件的同一线程中执行 - 因此在我的情况下,这就是刷新 ObservableCollection 的同一线程。因此,要刷新 UI,我不能像在单线程应用程序中那样直接使用绑定 - UI 必须通过 Dispatcher 手动刷新。但是当我在 UI 中使用 DataGrid 时,我得到的是空行而不是任何数据,例如,当我使用 ListBox 时,会显示适当的数据:
左侧是数据网格大小写,右侧是列表框大小写
(列表框只是数据绑定和显示的示例;我不希望数据像在此列表框中那样显示,而是像在数据网格中那样显示(如果它按我预期的那样工作 - 不是以防万一在图片上)- 带有列标题的表格)
嗯,我准备了代码,你可以复制粘贴来重构问题:
C#
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Threading;
using System.Windows;
namespace WpfApplication1
{
public class MyClass
{
public int Integer { get; set; }
public string Str { get; set; }
}
public partial class MainWindow : Window
{
public ObservableCollection<MyClass> MyCollection { get; set; }
public MainWindow()
{
InitializeComponent();
MyCollection = new ObservableCollection<MyClass>();
MyCollection.CollectionChanged += MyCollection_CollectionChanged;
Thread t = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 10; i++)
{
MyCollection.Add(new MyClass()
{
Integer = i,
Str = "String" + i
});
Thread.Sleep(500);
}
}));
t.Start();
}
void MyCollection_CollectionChanged(
object sender,
NotifyCollectionChangedEventArgs e)
{
Dispatcher.Invoke(
() =>
{
foreach (var item in e.NewItems)
dataGrid.Items.Add((MyClass)item);
});
}
}
}
XAML(只需注释/取消注释列表框大小写和数据网格大小写):
<Window
x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<!--<ListBox Name="dataGrid">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Integer}" />
<TextBlock Text="{Binding Path=Str}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>-->
<DataGrid Name="dataGrid">
<DataGrid.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Integer}" />
<TextBlock Text="{Binding Path=Str}" />
</StackPanel>
</DataTemplate>
</DataGrid.ItemTemplate>
</DataGrid>
</Grid>
</Window>
【问题讨论】:
-
DataGrid是一个非常复杂的控件。它的ItemTemplate不能正常工作(我们很少使用它)。我不认为我们可以改变 DataGrid 的设计布局,就像 grid 应该有一些列(至少 1 个)。在这种情况下,您没有为数据网格声明任何列,当将项目直接添加到Items属性时,AutoGenerateColumns似乎不起作用。所以你看到的只是空行。尝试添加一些显式的DataGridTextColumn并正确设置绑定,您会看到它有效。但是这里又看不到ItemTemplate的作用,在这里根本没用。 -
如果你想在 ListBox 中呈现一些结果,你可以使用 1
DataGridTemplateColumn然后编辑CellTemplate。
标签: c# wpf multithreading datagrid