WPF Linq到SQL返回一个带有数据绑定的自定义对象到DataGrid C#MVVM

本文关键字:数据绑定 自定义 对象 C#MVVM DataGrid 返回 SQL Linq WPF 一个 | 更新日期: 2023-09-27 18:28:30

我正试图从WinForms跳到WPF,并试图学习正确的方法。我想使用正确的MVVM模型。这是我的第一个WPF项目,我在使用linq结果进行数据绑定时遇到了问题。我知道我可以在代码后面很容易地做到这一点,甚至不使用自定义对象,并将整个表从linq查询返回到数据网格,同时仍然使用单独的类。但我想坚持这种形式。我不想使用数据表。

假设我有一个带有"Job"表的dbml。我想选择列"Job"(Linq似乎会自动将此列重命名为Job1)、"Customer"answers"Order_Date"。

这是我的代码:

namespace Custom_Teplate.Model
{
    public class LINQResult 
    {
        public System.String JobNum
        { get; set; }
        public System.String CustomerName
        { get; set; }
        public System.DateTime Order_Date
        {get; set; }
        public static LINQResult Create()
        {
            DataDataContext dc = new DataDataContext();
            dynamic query = (from ddd in dc.Jobs
                             where (ddd.Status == "Active")
                             select new LINQResult
                             {
                                 JobNum = ddd.Job1,
                                 CustomerName = ddd.Customer,
                                 Order_Date = ddd.Order_Date,   
                             });
           return query;
        }
    }
}

我将名称空间添加到我的XMAL:

xmlns:c="clr-namespace:Custom_Teplate.Model"
<Window.Resources>
    <c:LINQResult x:Key="ResultListData" />
</Window.Resources>

并将项目源设置为:

ItemsSource="{Binding Source={StaticResource ResultListData}}

WPF Linq到SQL返回一个带有数据绑定的自定义对象到DataGrid C#MVVM

我真的不会这么做。您的第一个错误是,尽管您已将LINQResult类的实例添加到Resources部分,但其中没有数据,因为您从未调用Create方法。这就是我将如何实现的:

我使用Linq2SQL访问数据库,并像您的示例一样填充自定义数据类型,但区别在于。。。我有一个每个视图的视图模型类。在视图模型类中,我有所有要在UI中显示的属性,无论它们是集合还是单个项。视图模型类通过基类实现INotifyPropertyChanged接口(这是必不可少的)。

我在App.xaml中设置了DataTemplate,将各种视图模型链接到视图,然后我可以在UI中显示这样的视图:

<ContentControl Content="{Binding ViewModel}" />

在视图模型构造函数中,我调用数据库并填充集合并设置属性。在您的示例中,您似乎正在创建一个Linq查询,该查询将返回多个项(IEnumerable<LINQResult>),但您试图从Create方法中只返回其中一个项。

我通常会为我的每个集合类扩展ObservableCollection<T>类,所以如果我是你,我会创建这个:

public class LinqResults : ObservableCollection<LinqResult> 
{
    public LinqResults(IEnumerable<LinqResult> linqResults) : base(linqResults) { }
}

然后我会把你的查询方法改成这样:

public static LinqResults Create()
{
    DataDataContext dc = new DataDataContext();
    LinqResults linqResults = new LinqResults(
        from job in dc.Jobs
        where job.Status == "Active"
        select new LinqResult
        {
            JobNum = job.Job1,
            CustomerName = job.Customer,
            Order_Date = job.Order_Date,
        });
    return linqResults;
}

然后在视图模型中,我将添加一个类型为LinqResults的集合属性,并将其"插入"到INotifyPropertyChanged接口:

public LinqResults LinqResults 
{
    get { return linqResults; }
    set { linqResults = value; NotifyPropertyChanged("LinqResults"); }
}

最后,绑定到视图中的集合,并为您的数据类型定义一个DataTemplate(记住定义一个XML命名空间来访问它):

    <ListBox ItemsSource="{Binding LinqResults}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type YourXmlNamespace:LinqResult}">
            <StackPanel>
                <TextBlock Text="{Binding JobNum}" />
                <TextBlock Text="{Binding CustomerName}" />
                <TextBlock Text="{Binding Order_Date}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

有关MVVM的更多信息,请参阅Josh Smith的WPF Apps With The Model View ViewModel Design Pattern文章。