[英]Binding a list/collection/IEnumerable of Model Class to a Data Grid and Selecting Columns
我似乎无法通过搜索找到此答案,也无法连接到其他示例到我的方案的点。
使用MVVM模式:
我将示例简化为:Model类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace TestListBinding.Models
{
public class ProjectModel
{
public string Id { get; set; }
public string ProjectTitle { get; set; }
public string ProjectDetails { get; set; }
}
}
ViewModel类:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using TestListBinding.Models;
namespace TestListBinding.ViewModels
{
public class ProjectViewModel
{
private ProjectModel _project;
private ObservableCollection<ProjectModel> _projects;
public ProjectViewModel()
{
_projects = new ObservableCollection<ProjectModel>();
var proj = new ProjectModel();
for (int i = 1; i <= 3; i++)
{
proj.Id = "ID" + i.ToString();
proj.ProjectTitle = "Project " + i.ToString();
proj.ProjectDetails = "Details about this: " + i.ToString();
_projects.Add(proj);
proj = new ProjectModel();
}
}
public IEnumerable<ProjectModel> Projects
{
get { return _projects; }
}
}
}
视图部分:
我知道我需要为视图提供一个DataContext
。 许多示例显示了它是在后台代码中设置的(请参见下文),还有一些示例引用了列表框的“ StaticResource”。 我没有找到一种通过UI设置代码的方式来设置绑定的方法。
MainWindow.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TestListBinding.ViewModels;
namespace TestListBinding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ProjectViewModel();//is this correct, or is there an alternative method via XAML/control properties?
}
}
}
XAML(通过代码或UI)能否请您帮助我完成数据网格列/绑定:每个@EdPlunkett更新
<Window x:Class="TestListBinding.MainWindow"
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:local="clr-namespace:TestListBinding"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid HorizontalAlignment="Left" Height="239" Margin="42,32,0,0" VerticalAlignment="Top" Width="435" ItemsSource="{Binding Projects}">
<DataGrid.Columns>
<DataGridTextColumn Header="Project Title" Binding="{Binding ProjectTitle}"/>
<DataGridTextColumn Header="Project Details" Binding="{Binding ProjectDetails}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
这在您的窗口构造函数中是正确的:
DataContext = new ProjectViewModel();
这应该向您显示网格中的一些内容:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="ID" />
<DataGridTextColumn Binding="{Binding ProjectTitle}" Header="Project Title" />
<DataGridTextColumn Binding="{Binding ProjectDetails}" Header="Project Details" />
</DataGrid.Columns>
WPF人员通常不使用设计器/属性窗格的内容。 它不是很好,并且十年来没有改善。 在这种情况下,您也无法自动完成。
首选控件? 取决于您要的内容:如果您希望每行多列,请使用DataGrid或ListView。 如果要每行显示一个值,或者每行显示某种漂亮的模板化UI,请使用ListBox。
快速清单框:
<ListBox
ItemsSource=“{Binding Projects}”
DisplayMemberPath=“ProjectTitle”
/>
DisplayMemberPath未绑定。 它是一个字符串,用于指定要在ListBox中显示的事物的属性的名称。
我将亲自进行下一个更改,尽管它是完全可选的。 您所拥有的将可以完美地工作: DataGrid.ItemsSource
不介意绑定到声明为IEnumerable<T>
的属性。 DataGrid.ItemsSource
的声明类型为非通用System.Collections.IEnumerable
。 但是公开这样的可观察集合是更常规的,并且通常很方便。
public ObservableCollection<ProjectModel> Projects
{
get { return _projects; }
}
当您说“模型类”时,我可能会弄错,但我想知道那里是否存在术语:您的ProjectModel
是模型类,因为它基本上是POCO(“计划旧CLR对象”),没有INotifyPropertyChanged
。 但是,由于它已绑定在UI中,因此如果用户可以更改其上的任何属性,则需要使用INPC的正确视图模型。 如果没有,请在该DataGrid上设置IsReadOnly="True"
。 如果项目只是计划UI中的无效只读数据,而没有任何行为,则像您拥有的POCO很好。 只要确保UI确实是只读的即可。
MVVM并不意味着拥有模型的ViewModel。 这意味着视图模型拥有的视图模型拥有其他视图模型,这些视图模型可能深达十几层,并且该视图模型“树”反映了应用程序的基本设计。 然后,您将获得模型,这些模型是一个独立的并行层次结构,反映了数据层的必要组织。 如果要通过Web服务从数据库加载项目,则可能会有一个ProjectModel和一个ProjectViewModel。 但是某些模型没有对应的视图模型,许多视图模型没有对应的模型。
而一个小型项目可能根本不需要“模型”层。 学习时,我会毫不犹豫地暂时编写视图模型和视图。 掌握那些和模型是无关紧要的。
模型就是数据。 一个ProjectViewModel可以包装一个ProjectModel,以暴露相同的属性,但具有INPC以及其他特定于UI的属性:例如IsDirty
(例如,如果它是可编辑的),或者UI绑定到ComboBoxes的查找列表(如果它具有枚举的属性)或查询类型。 它还将具有命令和方法。 除了编写包装器外,还有其他一些也许更好的方法,但是已经很晚了,可悲的是,我现在正在空白。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.