Entità vincolante in datagrid WPF con EF 7 (core)

c# data-binding entity-framework-core wpf

Domanda

Ho un semplice problema con l'associazione dei dati. Non sono in grado di ottenere il DataGrid DeviceDataGrid per visualizzare le informazioni sull'entità. Il file MainWindow.xaml è il seguente:

<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>

E cercando di visualizzare i dati all'interno dell'entità su MainWindow. Il database è stato creato correttamente e anche il pulsante Aggiungi funziona. Questo sono in grado di vedere con Firefox SQLite Manager.

Ecco il file xaml.cs che "lega" l'entità nel datagrid dopo aver caricato le entità nella memoria:

    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();
        }
    }
}

Poiché all'EF7 (core) manca ancora l'implementazione di local () sto usando un metodo di estensione alternativo .

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;
    }
}

Quando eseguo l'applicazione, il datagrid non mostra alcun valore dal database nella sua visualizzazione elenco. In qualche modo questa linea non trasferisce correttamente l'entità deviceViewSource.Source = _context.Devices.GetLocal(); O alcune procedure di associazione sono errate nel file xaml?

Qualche idea su cosa sto facendo male?

Risposta accettata

Il problema è che hai impostato deviceViewSource.Source su dispositivi, quindi sostituito con Categorie, quindi con ProductTypes

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

al e, si sta collegando a ProductTypes ... Rimuovere le due linee di fondo.

Credo che non sia necessario neanche il metodo GetLocal (). Prova questo:

deviceViewSource.Source = _context.Devices


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché