带有 MVVM 的 WPF 数据网格 [英] WPF datagrid with MVVM

查看:16
本文介绍了带有 MVVM 的 WPF 数据网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 WPF 中的数据网格绑定到我的 ViewModel,以便它将任何单元格更改更新到数据库,并允许用户删除行并添加新行.我已经有一部分工作了,但找不到 ADD 和修改的优雅解决方案.这是xaml

I'm trying to bind a datagrid in WPF to my ViewModel so that it will update any cell changes to the database as well as allow the user to delete rows and add new rows. I've got part of it working but can't find a ELEGANT solution for the ADD and modify. here is the xaml

<DataGrid AutoGenerateColumns="false" HorizontalAlignment="Left" Margin="26,41,0,0" Name="dataGrid1"   
              ItemsSource="{Binding Path=GetAllItems}" Height="200" VerticalAlignment="Top" Width="266" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=ItemListID}" Header="ID" Visibility="Hidden"/>
            <DataGridTextColumn Binding="{Binding Path=ItemName}" Header="Name" Width="4*" />
            <DataGridCheckBoxColumn Binding="{Binding Path=IsActive}" Header="Active" Width="*"  />
        </DataGrid.Columns>

然后在我的视图模型方法中

then in my view model method

private ObservableCollection< ItemsList> getAllItems()
{
    using (var context = new InspectorGeneralEntities())
    {
        var query = from I in context.ItemsLists
                    select I;

        var item = new ObservableCollection<ItemsList>(query.ToList());
        return item;
    }
}

在数据网格上删除一行或修改一行不会流入数据库.

Deleting a row or modifying a row on the datagrid does not flow onto the database.

a) 我需要在 xaml 代码中创建哪些其他绑定来检测这些事件

a) what other binding do i need to create in the xaml code that will detect these events

b) 我如何检测视图模型中已删除的记录或修改的项目,以便我可以在数据上下文不会自动更新的情况下进行更新.

b) How do i detect a removed record or modified item in the view model so that I can update the datacontext if it won't automatically.

推荐答案

我发现您问题中的代码存在一些问题.但是删除行没有反映在数据库中的原因是 .ToList() —— 本质上你正在创建一个新列表,它是 query 的副本,并且网格正在从该副本中删除元素.

I see a couple of problems with the code in your question. But the reason why deleting a row is not reflected in the database is the .ToList() -- essentially you're creating a new list which is a copy of query and the grid is removing elements from that copy.

您应该使用 ListCollectionView 并使用 Filter 而不是 linq 语句.

You should use a ListCollectionView and use a Filter instead of a linq statement.

以下是演示如何操作的示例:

Here's a sample showing how to do it:

1) 创建一个名为 ListCollectionViewTest

2) 在 MainWindow.xaml.cs 中剪切并粘贴以下内容(应该在 ViewModel 中,但我太懒了)

2) In the MainWindow.xaml.cs cut&paste the following (should be in ViewModel but I'm too lazy)

    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Data;

    namespace ListCollectionViewTest
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private List<Employee> equivalentOfDatabase = new List<Employee>()
                        {
                            new Employee() { FirstName = "John", LastName = "Doe", IsWorthyOfAttention = true },
                            new Employee() { FirstName = "Jane", LastName = "Doe", IsWorthyOfAttention = true },
                            new Employee() { FirstName = "Mr.", LastName = "Unsignificant", IsWorthyOfAttention = false },
                        };

            public ListCollectionView TestList { get; set; }
            public MainWindow()
            {
                DataContext = this;

                // This is all the magic you need -------
                TestList = new ListCollectionView(equivalentOfDatabase);
                TestList.Filter = x => (x as Employee).IsWorthyOfAttention;

                InitializeComponent();
            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show(equivalentOfDatabase.Aggregate("Employees are: 

", (acc, emp) => acc + string.Format("    - {0} {1}

", emp.FirstName, emp.LastName), x => x));
            }
        }

        public class Employee
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public bool IsWorthyOfAttention { get; set; }
        }
    }

3) 在 MainWindow.xaml 中剪切并粘贴:

3) In MainWindow.xaml cut&paste this:

    <Window x:Class="ListCollectionViewTest.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">

        <StackPanel>
            <DataGrid ItemsSource="{Binding TestList}"
                      RowHeight="22"
                      AutoGenerateColumns="True">
            </DataGrid>
            <Button Content="Show All Employees in DB" Click="Button_Click" />
        </StackPanel>        
    </Window>

这篇关于带有 MVVM 的 WPF 数据网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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