将实体绑定到具有EF 7(核心)的WPF数据网格中 [英] Binding entity into WPF datagrid with EF 7 (core)

查看:165
本文介绍了将实体绑定到具有EF 7(核心)的WPF数据网格中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的数据绑定问题。我不能得到datagrid DeviceDataGrid 可视化实体信息。 MainWindow.xaml 文件如下:

 < Window 
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
xmlns:d =http://schemas.microsoft.com/expression/blend/2008xmlns:mc =http://schemas.openxmlformats.org/markup-compatibility/2006xmlns:domain = clr-namespace:FxEditorDatabaseStructure.Core.Domain
mc:Ignorable =dx:Class =FxEditorDatabaseStructure.MainWindow
Title =MainWindowHeight =350Width =525 =Window_Loaded>
< Window.Resources>
< CollectionViewSource x:Key =DeviceViewSourced:DesignSource ={d:DesignInstance {x:Type domain:Device},CreateList = True}/>
< /Window.Resources>
< Grid DataContext ={StaticResource DeviceViewSource}>
< DataGrid x:Name =DeviceDataGridAutoGenerateColumns =FalseEnableRowVirtualization =TrueItemsSource ={Binding}Margin =0,64,0,0RowDetailsVisibilityMode =VisibleWhenSelected>
< DataGrid.Columns>
< DataGridTextColumn x:Name =NameColumnBinding ={Binding Name}Header =NameWidth =250/>
< DataGridTextColumn x:Name =SocketCountColumnBinding ={Binding DeviceId}Header =IdWidth =Auto/>
< DataGridTextColumn x:Name =DescriptionColumnBinding ={Binding Description}Header =DescriptionWidth =Auto/>
< DataGridTextColumn x:Name =ProductTypeColumnBinding ={Binding ProductType}Header =Product TypeWidth =*/>
< /DataGrid.Columns>
< / DataGrid>
< Button Content =AddHorizo​​ntalAlignment =LeftMargin =23,25,0,0VerticalAlignment =TopWidth =75RenderTransformOrigin = - 0.143,-0.057Click = AddDevice_Click/>
< / Grid>
< / Window>

并尝试在MainWindow上的实体中可视化数据。
正确创建数据库,甚至添加按钮也可以正常工作。我可以使用Firefox SQLite Manager查看。



这是一个xaml.cs文件,它将实体加载到数据网格后,将实体加载到内存中:

  public partial class MainWindow:Window 
{
private FxContext _context = new FxContext();

public MainWindow()
{
InitializeComponent();
_context.Database.Migrate();
}
private void Window_Loaded(object sender,RoutedEventArgs e)
{
_context.Devices.Add(new Device
{
ProductCode =100 ,
Name =LUX999,
描述=Measurement device,
Supplier =X,
Category =Sensors,
ProductType =Field设备,
TimeCreated = DateTime.Now
});
_context.SaveChanges();

System.Windows.Data.CollectionViewSource deviceViewSource =((System.Windows.Data.CollectionViewSource)(this.FindResource(DeviceViewSource)));
_context.Devices.Load();
_context.Sockets.Load();
_context.ProductTypes.Load();
deviceViewSource.Source = _context.Devices.GetLocal();
deviceViewSource.Source = _context.Categories.GetLocal();
deviceViewSource.Source = _context.ProductTypes.GetLocal();
}

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);

_context.Dispose();
}

private void AddDevice_Click(object sender,RoutedEventArgs e)
{
_context.Devices.Add(
new Device
{
TimeCreated = DateTime.Now,
Name =New Device at+ DateTime.Now.ToShortDateString()
});

_context.SaveChanges();
}
}
}

因为EF7(核心)仍然缺少local()的实现我正在使用一个替代扩展方法

  public static class Extensions 
{
public static ObservableCollection< TEntity> GetLocal< TEntity>(此DbSet< TEntity>集合)
其中TEntity:class
{
var context = set.GetService< DbContext>();
var data = context.ChangeTracker.Entries< TEntity>()。选择(e => e.Entity);
var collection = new ObservableCollection< TEntity>(data);

collection.CollectionChanged + =(s,e)=>
{
if(e.NewItems!= null)
{
context.AddRange(e.NewItems.Cast< TEntity>());
}

if(e.OldItems!= null)
{
context.RemoveRange(e.OldItems.Cast< TEntity>());
}
};

return collection;
}
}

当我运行应用程序时,datagrid不显示任何在数据库的列表视图中的值。不知怎的,这行不正确地转移实体的 deviceViewSource.Source = _context.Devices.GetLocal(); 或一些绑定过程在xaml文件中是错误的



任何想法我做错了什么?

解决方案

问题是,您将 deviceViewSource.Source ,然后替换为Categories,然后使用ProductTypes

  deviceViewSource.Source = _context.Devices.GetLocal(); 
deviceViewSource.Source = _context.Categories.GetLocal();
deviceViewSource.Source = _context.ProductTypes.GetLocal();

在,而您正在将数据绑定到ProductTypes ...删除两条底线。



我相信你不需要GetLocal()方法。尝试这样:

  deviceViewSource.Source = _context.Devices 


I have a simple problem with data binding. I'm not able to get the datagrid DeviceDataGrid to visualise the entity information. The MainWindow.xaml file is as follows:

<Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:domain="clr-namespace:FxEditorDatabaseStructure.Core.Domain"
    mc:Ignorable="d" x:Class="FxEditorDatabaseStructure.MainWindow"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>
        <CollectionViewSource x:Key="DeviceViewSource" d:DesignSource="{d:DesignInstance {x:Type domain:Device}, CreateList=True}"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource DeviceViewSource}">
        <DataGrid x:Name="DeviceDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Margin="0,64,0,0" RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="NameColumn" Binding="{Binding Name}" Header="Name" Width="250"/>
                <DataGridTextColumn x:Name="SocketCountColumn" Binding="{Binding DeviceId}" Header="Id" Width="Auto"/>
                <DataGridTextColumn x:Name="DescriptionColumn" Binding="{Binding Description}" Header="Description" Width="Auto"/>
                <DataGridTextColumn x:Name="ProductTypeColumn" Binding="{Binding ProductType}" Header="Product Type" Width="*"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button Content="Add" HorizontalAlignment="Left" Margin="23,25,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="-0.143,-0.057" Click="AddDevice_Click"/>
    </Grid>
</Window>

And trying to visualise the data within the entity on MainWindow. The database is correctly created and even the add button works. This I am able to see with Firefox SQLite Manager.

Here is the xaml.cs file which is "binding" the entity into the datagrid after eager loading entities into memory:

    public partial class MainWindow : Window
    {
        private FxContext _context = new FxContext();

        public MainWindow()
        {
            InitializeComponent();
            _context.Database.Migrate();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            _context.Devices.Add(new Device
            {
                ProductCode = "100",
                Name = "LUX999",
                Description = "Measurement device",
                Supplier = "X",
                Category = "Sensors",
                ProductType = "Field device",
                TimeCreated = DateTime.Now
            });
            _context.SaveChanges();

            System.Windows.Data.CollectionViewSource deviceViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("DeviceViewSource")));
            _context.Devices.Load();
            _context.Sockets.Load();
            _context.ProductTypes.Load();
            deviceViewSource.Source = _context.Devices.GetLocal();
            deviceViewSource.Source = _context.Categories.GetLocal();
            deviceViewSource.Source = _context.ProductTypes.GetLocal();
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);

            _context.Dispose();
        }

        private void AddDevice_Click(object sender, RoutedEventArgs e)
        {
            _context.Devices.Add(
                new Device
                {
                    TimeCreated = DateTime.Now,
                    Name = "New Device at " + DateTime.Now.ToShortDateString()
                });

            _context.SaveChanges();
        }
    }
}

Because the EF7 (core) still lacks the implementation of local() I'm using an alternative extension method.

public static class Extensions
{
    public static ObservableCollection<TEntity> GetLocal<TEntity>(this DbSet<TEntity> set)
        where TEntity : class
    {
        var context = set.GetService<DbContext>();
        var data = context.ChangeTracker.Entries<TEntity>().Select(e => e.Entity);
        var collection = new ObservableCollection<TEntity>(data);

        collection.CollectionChanged += (s, e) =>
        {
            if (e.NewItems != null)
            {
                context.AddRange(e.NewItems.Cast<TEntity>());
            }

            if (e.OldItems != null)
            {
                context.RemoveRange(e.OldItems.Cast<TEntity>());
            }
        };

        return collection;
    }
}

When I run the application the datagrid is not showing any values from the database in its list view. Somehow this line is not transferring the entity correctly deviceViewSource.Source = _context.Devices.GetLocal(); OR some binding procedure is wrong in the xaml-file?

Any ideas what I'm doing wrong?

解决方案

The problem is, that you set deviceViewSource.Source to devices, then replaced with Categories, then with ProductTypes

deviceViewSource.Source = _context.Devices.GetLocal();
deviceViewSource.Source = _context.Categories.GetLocal();
deviceViewSource.Source = _context.ProductTypes.GetLocal();

at the and, you are databanding to ProductTypes... Remove the two bottom lines.

I believe that you dont need the GetLocal() method neither. Try this:

deviceViewSource.Source = _context.Devices

这篇关于将实体绑定到具有EF 7(核心)的WPF数据网格中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆