使用MVVM的WPF数据网格 [英] WPF datagrid with MVVM

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

问题描述

我试图将WPF中的datagrid绑定到我的ViewModel,以便它将更新任何单元格更改到数据库,并允许用户删除行并添加新的行。我有一部分工作,但找不到ELEGANT解决方案的ADD和修改。
这里是xaml

 < DataGrid AutoGenerateColumns =falseHorizo​​ntalAlignment =LeftMargin =26, 41,0,0Name =dataGrid1
ItemsSource ={Binding Path = GetAllItems}Height =200VerticalAlignment =TopWidth =266>
< DataGrid.Columns>
< DataGridTextColumn Binding ={Binding Path = ItemListID}Header =IDVisibility =Hidden/>
< DataGridTextColumn Binding ={Binding Path = ItemName}Header =NameWidth =4 */>
< DataGridCheckBoxColumn Binding ={Binding Path = IsActive}Header =ActiveWidth =*/>
< /DataGrid.Columns>



然后在我的视图模型方法

  private ObservableCollection< ItemsList> getAllItems()
{
使用(var context = new InspectorGeneralEntities())
{
var query =从我在context.ItemsLists
中选择I;

var item = new ObservableCollection< ItemsList>(query.ToList());
返回项目;
}
}

删除一行或修改datagrid上的一行不要流入数据库。



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



b)如何在视图模型中检测删除的记录或修改的项目,以便我可以自动更新数据文本。

解决方案

我看到你的问题中的代码有几个问题。但是删除一行的原因是没有反映在数据库中的是 .ToList() - 基本上你正在创建一个新的列表,它是一个查询的副本,网格正在从该副本中删除元素。



您应该使用 ListCollectionView 并使用过滤器而不是linq语句



下面是一个示例,显示如何做:



1)创建一个名为



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

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

命名空间ListCollectionViewTest
{
///< summary>
/// 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 =Jane,LastName =Doe,IsWorthyOfAttention = true},
new Employee(){FirstName =Mr.,LastName =Unsidentificant,IsWorthyOfAttention = false},
};

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

//这是所有你需要的魔法-------
TestList = new ListCollectionView(equivalentOfDatabase);
TestList.Filter = x => (x作为员工)。值得注意;

InitializeComponent();
}

private void Button_Click(object sender,RoutedEventArgs e)
{
MessageBox.Show(equivalentOfDatabase.Aggregate(Employees are:\\\
\r ,(acc,emp)=> acc + string.Format( - {0} {1} \\\
\r,emp.FirstName,emp.LastName),x => x));
}
}

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

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

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

< StackPanel>
< DataGrid ItemsSource ={Binding TestList}
RowHeight =22
AutoGenerateColumns =True>
< / DataGrid>
< Button Content =显示DB中的所有员工Click =Button_Click/>
< / StackPanel>
< / Window>


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) what other binding do i need to create in the xaml code that will detect these events

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.

解决方案

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.

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

Here's a sample showing how to do it:

1) Create a new WPF project called ListCollectionViewTest

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: \n\r", (acc, emp) => acc + string.Format("    - {0} {1}\n\r", 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) 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天全站免登陆