【问题标题】:Binding a list/collection/IEnumerable of Model Class to a Data Grid and Selecting Columns将模型类的列表/集合/IEnumerable 绑定到数据网格并选择列
【发布时间】:2019-10-07 08:02:48
【问题描述】:

我似乎无法通过搜索找到此答案,也无法将其他示例中的点连接到我的场景。

使用 MVVM 模式:

  1. 如何通过视图中的 ViewModel 将模型类绑定到列表框/数据网格?
  2. 如何挑选要显示的列?
  3. 问题 2 跟进:我可以通过 Visual Studio UI 属性进行选择吗?如果可以,如何选择?
  4. 如果使用 XAML 完成,我的模型/视图模型类是否会自动完成?
  5. 使用Observable Collection,正确的实现方式是什么?
  6. 什么是“首选”XAML 控件(数据网格?、列表框?等)

我已将示例简化为: 模型类:

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>

这会产生一个带有额外列的奇怪布局:

【问题讨论】:

    标签: c# wpf mvvm data-binding wpfdatagrid


    【解决方案1】:

    这在您的窗口构造函数中是正确的:

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

    【讨论】:

    • 感谢您的详细回复。我已根据您的 cmets 更新了 XAML 代码并添加了屏幕截图。令人震惊的是,我得到的列比指定的要多。另外,对于这个例子,我绕过了我的数据库层,理想情况下,它会在视图和数据库之间来回更新。
    • 哎呀,忘了说,在 DataGrid 上设置 AutoGenerateColumns=“False”。听起来您确实想要一个 DataGrid,并且项目类是一个合适的视图模型。
    • 解决了! ...如何触发将单元格/网格值更改回视图模型?
    • 网格会通过绑定更新viewmodel属性。
    • 它会引发事件吗?我需要订阅它吗?你能解释一下吗?(我已将 Projects 属性更改为 ObservableCollection
    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多