使用 EF 7(核心)将实体绑定到 WPF 数据网格中
本文关键字:WPF 数据 数据网 网格 绑定 实体 EF 核心 使用 | 更新日期: 2023-09-27 18:32:59
我在数据绑定方面有一个简单的问题。我无法获取数据网格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/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>
并尝试在 MainWindow 上可视化实体中的数据。数据库已正确创建,甚至添加按钮也有效。我能够用Firefox SQLite管理器看到这一点。
下面是 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",
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();
}
}
}
由于 EF7(核心)仍然缺乏 local() 的实现,所以我正在使用替代扩展方法。
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;
}
}
当我运行应用程序时,数据网格在其列表视图中没有显示数据库中的任何值。不知何故,此行没有正确传输实体deviceViewSource.Source = _context.Devices.GetLocal();
或者 xaml 文件中的某些绑定过程是错误的?
知道我做错了什么吗?
问题是,您将deviceViewSource.Source
设置为设备,然后替换为类别,然后替换为产品类型
deviceViewSource.Source = _context.Devices.GetLocal();
deviceViewSource.Source = _context.Categories.GetLocal();
deviceViewSource.Source = _context.ProductTypes.GetLocal();
在和,您正在数据波段到产品类型...删除两条底线。
我相信你也不需要 GetLocal() 方法。试试这个:
deviceViewSource.Source = _context.Devices