DbSet 和 ObservableCollection 之间的转换
Conversion between DbSet and ObservableCollection
构建 WPF 应用程序并尝试使事情变得相当简单。
目的是我有一个绑定到 Observable 集合的数据网格。后台有一个频繁的任务 运行,它会定期将项目添加到集合中,我希望这些立即显示在 UI 数据网格上。
我遇到的两个问题:
- 当集合更新时,数据网格没有。如果我的 ServiceLayer 知道有关 UserControl 的任何信息,我会调用 Datagrid.Refresh(),但它不知道,所以我不能。我知道我需要某种 PropertyChanged 事件才能触发,我可以在我的代码中引发自定义事件,但我该如何让视图响应?
我的 Xaml - 我稍后会正确格式化数据网格。
<UserControl x:Class="FrontEnd.Views.ItemsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FrontEnd.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
DataContext="{Binding ViewModel, Source={StaticResource ViewModelLocator}}">
<Grid>
<DataGrid x:Name="Items"
HorizontalAlignment="Left"
Height="auto"
VerticalAlignment="Top"
Width="auto"
AutoGenerateColumns="True"
ColumnWidth="*"
ItemsSource="{Binding ExistingItems}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Title}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
public ObservableCollection<Item> ExistingItems
{
get
{
return _existingItems;
}
private set
{
_existingItems = value;
//Raise PropertyChangedEvent?
}
}
第二个问题在 DataLayer 中 - Item 有一个组的外键 table,当我显示 Items 时,我想显示组的名称,所以我的 DataLayer 中有以下内容
ICollection items = _context.Items.Include(i => i.Group);
return items;
但现在我想使 Items Observable,我不能这样做 - 我可以使用
ObservableCollection items = _context.Items.Local;
return items;
到 return 一个不包含 Group 实体数据的 ObservableCollection,但是我需要单独获取 Group 数据并在 ViewModel 中进行基于代码的连接,我宁愿不这样做做。
return (ObservableCollection<Item>)_context.Items.Include(i => i.Group);
不出所料在运行时失败。
我觉得我在这两个问题上都遗漏了一些明显的东西。有谁能给点建议吗?
您应该 implement INotifyPropertyChanged
接口并从 ExistingItems
属性 的 setter 引发 PropertyChanged
事件,或者只需将新项目添加到 ObservableCollection<Item>
的现有实例,而不是创建新项目:
ExistingItems.Clear();
foreach (vew newItem in collectionFromDal)
ExistingItems.Add(newItem);
你的 DAL 应该 return 一个集合:
_context.Items.Include(i => i.Group).ToArray();
或
new ObservableCollection<Item>(_context.Items.Include(i => i.Group));
理想情况下,您会在客户端应用程序的视图模型中创建 ObservableCollection<Item>
。
我经常发现 UI 元素不响应模型中列表的更新,即使使用绑定。当您更新模型中的列表时,您还可以尝试 System.Windows.Application.Current.Dispatcher.Invoke(() => {code to update your model here});
不理想,但可能会解决您的问题。
构建 WPF 应用程序并尝试使事情变得相当简单。 目的是我有一个绑定到 Observable 集合的数据网格。后台有一个频繁的任务 运行,它会定期将项目添加到集合中,我希望这些立即显示在 UI 数据网格上。
我遇到的两个问题:
- 当集合更新时,数据网格没有。如果我的 ServiceLayer 知道有关 UserControl 的任何信息,我会调用 Datagrid.Refresh(),但它不知道,所以我不能。我知道我需要某种 PropertyChanged 事件才能触发,我可以在我的代码中引发自定义事件,但我该如何让视图响应?
我的 Xaml - 我稍后会正确格式化数据网格。
<UserControl x:Class="FrontEnd.Views.ItemsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FrontEnd.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
DataContext="{Binding ViewModel, Source={StaticResource ViewModelLocator}}">
<Grid>
<DataGrid x:Name="Items"
HorizontalAlignment="Left"
Height="auto"
VerticalAlignment="Top"
Width="auto"
AutoGenerateColumns="True"
ColumnWidth="*"
ItemsSource="{Binding ExistingItems}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Title}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
public ObservableCollection<Item> ExistingItems
{
get
{
return _existingItems;
}
private set
{
_existingItems = value;
//Raise PropertyChangedEvent?
}
}
第二个问题在 DataLayer 中 - Item 有一个组的外键 table,当我显示 Items 时,我想显示组的名称,所以我的 DataLayer 中有以下内容
ICollection items = _context.Items.Include(i => i.Group);
return items;
但现在我想使 Items Observable,我不能这样做 - 我可以使用
ObservableCollection items = _context.Items.Local;
return items;
到 return 一个不包含 Group 实体数据的 ObservableCollection,但是我需要单独获取 Group 数据并在 ViewModel 中进行基于代码的连接,我宁愿不这样做做。
return (ObservableCollection<Item>)_context.Items.Include(i => i.Group);
不出所料在运行时失败。
我觉得我在这两个问题上都遗漏了一些明显的东西。有谁能给点建议吗?
您应该 implement INotifyPropertyChanged
接口并从 ExistingItems
属性 的 setter 引发 PropertyChanged
事件,或者只需将新项目添加到 ObservableCollection<Item>
的现有实例,而不是创建新项目:
ExistingItems.Clear();
foreach (vew newItem in collectionFromDal)
ExistingItems.Add(newItem);
你的 DAL 应该 return 一个集合:
_context.Items.Include(i => i.Group).ToArray();
或
new ObservableCollection<Item>(_context.Items.Include(i => i.Group));
理想情况下,您会在客户端应用程序的视图模型中创建 ObservableCollection<Item>
。
我经常发现 UI 元素不响应模型中列表的更新,即使使用绑定。当您更新模型中的列表时,您还可以尝试 System.Windows.Application.Current.Dispatcher.Invoke(() => {code to update your model here});
不理想,但可能会解决您的问题。