EF 7 (코어)으로 WPF DataGrid에 엔터티 바인딩

c# data-binding entity-framework-core 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/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 Manager에서 볼 수 있습니다.

엔티티를 메모리에 로딩 한 후 DataGrid에 엔터티를 "바인딩"하는 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;
    }
}

응용 프로그램을 실행할 때 DataGrid는 목록보기에서 데이터베이스의 값을 표시하지 않습니다. 어떻게 든이 행은 엔티티를 올바르게 전송하지 않습니다. deviceViewSource.Source = _context.Devices.GetLocal(); 또는 일부 바인딩 절차가 xaml 파일에서 잘못 되었습니까?

내가 뭘 잘못하고 있는거야?

수락 된 답변

문제는 deviceViewSource.Source 를 기기로 설정 한 다음 카테고리로 대체 한 다음 ProductTypes로 대체한다는 것입니다.

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

and에서 ProductTypes로 데이터를 이동하는 중입니다 ... 두 개의 하단 라인을 제거하십시오.

나는 GetLocal () 메소드가 필요 없다고 생각한다. 이 시도:

deviceViewSource.Source = _context.Devices



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.