动态更新绑定的 DataGrid
Updating Binded DataGrid Dynamically
我正在尝试将 DataGrid 与 ObservableCollection 列表绑定。我基本上在表单的开头向列表中添加了一些项目(应该向数据网格中添加行),然后在不同的线程中使用此代码动态更新列:
UserDataGrid.Dispatcher.BeginInvoke(new Action(() =>
{
UserDataGridCollection[m_iID].Status = Log;
UserDataGridCollection[m_iID].ID = m_iID;
UserDataGridCollection[m_iID].User = m_sUser;
}
如果我以这种方式更新 DataGrid,它会工作但滞后于 UI 线程:
UserDataGrid.ItemsSource = null;
UserDataGrid.ItemsSource = UserDataGridCollection;
我试过使用 PropertyChanged 事件,但 DataGrid 没有首先填充,所以我不确定它是否正常工作。这是我的数据 class:
public class UserDataGridCategory : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int id;
private string user, status;
public int ID
{
get { return id; }
set { id = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ID")); }
}
public string User
{
get { return user; }
set { user = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("User")); }
}
public string Status
{
get { return status; }
set { status = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Status")); }
}
}
这是我创建 ObservableCollection 的方式:
static class UserEngine
{
public static ObservableCollection<UserDataGridCategory> UserDataGridCollection { get; set; }
public static object _lock = new object();
public static void RunEngine(DataGrid UserDataGrid)
{
UserDataGridCollection = new ObservableCollection<UserDataGridCategory>();
BindingOperations.EnableCollectionSynchronization(UserDataGridCollection, _lock);
// Some other code
// Spawn thread to invoke dispatcher and do some other stuff
}
}
这是我的 xaml:
<DataGrid Name="UserDataGrid" x:FieldModifier="public" ItemsSource="{Binding UserDataGridCollection}" SelectedItem="{Binding SelectedRow, Mode=TwoWay}" Margin="10,16,22.6,215" AutoGenerateColumns="False" IsReadOnly="True">
<DataGrid.Resources>
<ContextMenu x:Key="RowMenu" Focusable="False"
DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="View Log" Click="ViewLog" Focusable="False"/>
</ContextMenu>
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="ID #" Binding="{Binding ID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"/>
<DataGridTextColumn Header="User" Binding="{Binding User, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Width="150"/>
<DataGridTextColumn Header="Status" Binding="{Binding Status,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Width="250"/>
</DataGrid.Columns>
</DataGrid>
非常感谢任何帮助,谢谢!
也许它有助于将您的 itemsource 绑定到 CollectionViewSource 而不是可观察的集合。
public class UserEngine {
public ICollectionView UserdataCollectionView { get; set; }
public UserEngine() { 'constructor
UserdataCollectionView = CollectionViewSource.GetDefaultView(UserDataGridCollection );
}
public void addnewLinetoOC(){
// after you add a new entry into your observable collection
UserdataCollectionView .Refresh();
}
}
在你的xaml中你必须设置
ItemsSource="{Binding UserdataCollectionView }"
不能 100% 确定此解决方案是否适合您的问题,但这就是我解决向视图模型中的可观察集合添加新项目的方法。
我正在尝试将 DataGrid 与 ObservableCollection 列表绑定。我基本上在表单的开头向列表中添加了一些项目(应该向数据网格中添加行),然后在不同的线程中使用此代码动态更新列:
UserDataGrid.Dispatcher.BeginInvoke(new Action(() =>
{
UserDataGridCollection[m_iID].Status = Log;
UserDataGridCollection[m_iID].ID = m_iID;
UserDataGridCollection[m_iID].User = m_sUser;
}
如果我以这种方式更新 DataGrid,它会工作但滞后于 UI 线程:
UserDataGrid.ItemsSource = null;
UserDataGrid.ItemsSource = UserDataGridCollection;
我试过使用 PropertyChanged 事件,但 DataGrid 没有首先填充,所以我不确定它是否正常工作。这是我的数据 class:
public class UserDataGridCategory : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int id;
private string user, status;
public int ID
{
get { return id; }
set { id = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ID")); }
}
public string User
{
get { return user; }
set { user = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("User")); }
}
public string Status
{
get { return status; }
set { status = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Status")); }
}
}
这是我创建 ObservableCollection 的方式:
static class UserEngine
{
public static ObservableCollection<UserDataGridCategory> UserDataGridCollection { get; set; }
public static object _lock = new object();
public static void RunEngine(DataGrid UserDataGrid)
{
UserDataGridCollection = new ObservableCollection<UserDataGridCategory>();
BindingOperations.EnableCollectionSynchronization(UserDataGridCollection, _lock);
// Some other code
// Spawn thread to invoke dispatcher and do some other stuff
}
}
这是我的 xaml:
<DataGrid Name="UserDataGrid" x:FieldModifier="public" ItemsSource="{Binding UserDataGridCollection}" SelectedItem="{Binding SelectedRow, Mode=TwoWay}" Margin="10,16,22.6,215" AutoGenerateColumns="False" IsReadOnly="True">
<DataGrid.Resources>
<ContextMenu x:Key="RowMenu" Focusable="False"
DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="View Log" Click="ViewLog" Focusable="False"/>
</ContextMenu>
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="ID #" Binding="{Binding ID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"/>
<DataGridTextColumn Header="User" Binding="{Binding User, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Width="150"/>
<DataGridTextColumn Header="Status" Binding="{Binding Status,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Width="250"/>
</DataGrid.Columns>
</DataGrid>
非常感谢任何帮助,谢谢!
也许它有助于将您的 itemsource 绑定到 CollectionViewSource 而不是可观察的集合。
public class UserEngine {
public ICollectionView UserdataCollectionView { get; set; }
public UserEngine() { 'constructor
UserdataCollectionView = CollectionViewSource.GetDefaultView(UserDataGridCollection );
}
public void addnewLinetoOC(){
// after you add a new entry into your observable collection
UserdataCollectionView .Refresh();
}
}
在你的xaml中你必须设置
ItemsSource="{Binding UserdataCollectionView }"
不能 100% 确定此解决方案是否适合您的问题,但这就是我解决向视图模型中的可观察集合添加新项目的方法。