DbSet 和 ObservableCollection 之间的转换

Conversion between DbSet and ObservableCollection

构建 WPF 应用程序并尝试使事情变得相当简单。 目的是我有一个绑定到 Observable 集合的数据网格。后台有一个频繁的任务 运行,它会定期将项目添加到集合中,我希望这些立即显示在 UI 数据网格上。

我遇到的两个问题:

  1. 当集合更新时,数据网格没有。如果我的 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});

不理想,但可能会解决您的问题。