简体   繁体   English

DbSet 和 ObservableCollection 之间的转换

[英]Conversion between DbSet and ObservableCollection

Building a WPF App and trying to keep things fairly simple.构建一个 WPF 应用程序并尝试让事情变得相当简单。 The intention is that I have a datagrid bound to an Observable collection.目的是我有一个绑定到 Observable 集合的数据网格。 There is a frequent task running in the background that will periodicially ADD items to the collection and I'd like these to be immediately displayed on the UI datagrid.在后台运行的频繁任务将定期将项目添加到集合中,我希望这些项目立即显示在 UI 数据网格上。

The two problems I've got:我遇到的两个问题:

  1. WHen the colletion is updated, the datagrid isn't.当集合更新时,数据网格不会。 If my ServiceLayer knew anything about the UserControl I'd just call Datagrid.Refresh(), but it doesn't so I can't.如果我的 ServiceLayer 知道有关 UserControl 的任何信息,我只会调用 Datagrid.Refresh(),但它不知道,所以我不能。 I understand I need some kind of PropertyChanged event to fire and I can raise a custom event in my code, but how do I make the View respond?我知道我需要某种 PropertyChanged 事件来触发,我可以在我的代码中引发一个自定义事件,但是如何让 View 响应?

My Xaml - I'll format the datagrid properly later.我的 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?
            }
        }

The second issue is in the DataLayer - Item has a foreign key to a Group table and when I display the Items I want to show the name of the Group so I had the following in my DataLayer第二个问题是在 DataLayer - Item 有一个 Group 表的外键,当我显示 Items 时,我想显示 Group 的名称,所以我的 DataLayer 中有以下内容

ICollection items = _context.Items.Include(i => i.Group);
return items;

But now I want to make Items Observable, I can't do this - I could use但是现在我想让 Items Observable,我不能这样做 - 我可以使用

ObservableCollection items = _context.Items.Local;
return items;

to return an ObservableCollection that DOESN'T include the Group entity data but then I'd need to separately grab the Group data and do a code-based join in the ViewModel which I'd rather not do.返回一个不包含 Group 实体数据的 ObservableCollection,但是我需要单独获取 Group 数据并在 ViewModel 中进行基于代码的连接,而我不想这样做。

return (ObservableCollection<Item>)_context.Items.Include(i => i.Group);

unsurprisingly fails at runtime.不出所料地在运行时失败。

I feel I'm missing something obvious with both issues.我觉得我在这两个问题上都遗漏了一些明显的东西。 Can anyone advise please?有人可以建议吗?

You should either implement the INotifyPropertyChanged interface and raise the PropertyChanged event from the setter of the ExistingItems property, or just add the new items to the existing instance of the ObservableCollection<Item> instead of creating a new one:您应该实现INotifyPropertyChanged接口并从ExistingItems属性的设置器中引发PropertyChanged事件,或者只是将新项目添加到ObservableCollection<Item>的现有实例中,而不是创建一个新实例:

ExistingItems.Clear();
foreach (vew newItem in collectionFromDal)
    ExistingItems.Add(newItem);

Your DAL should return a collection:您的 DAL 应该返回一个集合:

_context.Items.Include(i => i.Group).ToArray();

or或者

new ObservableCollection<Item>(_context.Items.Include(i => i.Group));

Ideally, you would create the ObservableCollection<Item> in the view model in the client app.理想情况下,您将在客户端应用程序的视图 model 中创建ObservableCollection<Item>

Often times even with binding I find that the UI element isn't responding to updates to lists in the model.即使有绑定,我也经常发现 UI 元素没有响应 model 中列表的更新。 When you update the list in your model you can also try System.Windows.Application.Current.Dispatcher.Invoke(() => {code to update your model here});当您更新 model 中的列表时,您还可以尝试 System.Windows.Application.Current.Dispatcher.Invoke(() => {此处更新 model 的代码});

Not ideal but will likely resolve your issue.不理想,但可能会解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM