簡體   English   中英

將模型類的列表/集合/ IEnumerable綁定到數據網格並選擇列

[英]Binding a list/collection/IEnumerable of Model Class to a Data Grid and Selecting Columns

我似乎無法通過搜索找到此答案,也無法連接到其他示例到我的方案的點。

使用MVVM模式:

  1. 如何通過視圖中的ViewModel將模型類綁定到列表框/數據網格?
  2. 如何選擇要顯示的列?
  3. 問題2后續行動:我可以通過visual Studio UI屬性進行選擇嗎?如果可以,如何選擇?
  4. 如果使用XAML完成,我的模型/視圖模型類是否可以自動完成?
  5. 使用Observable Collection,什么是正確的實現方式?
  6. 什么是“首選” XAML控件(datagrid,listbox等)

我將示例簡化為: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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM