欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

『WPF』DataGrid的使用

程序员文章站 2022-07-14 08:50:45
...

几点说明


  • 这里主要是参考了MSDN中关于DataGrid的说明
  • 这里只会简单说明在WPF中,DataGird最简单的使用方法
  • 对于MSDN中的翻译不会很详细,也不会每一句都翻译。

 

来自MSDN的内容


Type Name Description
Constructors DataGrid Initializes a new instance of the System.Windows.Controls.DataGrid class.
Property ItemsSource Gets or sets a collection that is used to generate the content of the control.
  AutoGenerateColumns Gets or sets a value that indicates whether columns are created automatically when the ItemsSource property is set.

 

The DataGrid control provides a flexible way to display a collection of data in rows and columns. The built-in column types include a text box column, a check box column, and a template column for hosting custom content. The built-in row type includes a drop-down details section that you can use to display additional content below the cell values.

内建的列类型包括:

  1. 文本框
  2. 复选框
  3. 模板列

内建的行类型包括:

  • 下拉列表

『WPF』DataGrid的使用

Binding to Data

To bind the DataGrid to data, set the ItemsSource property to an IEnumerable implementation. Each row in the data grid is bound to an object in the data source, and each column in the data grid is bound to a property of the data object. In order for the DataGrid user interface to update automatically when items are added to or removed from the source data, the DataGrid must be bound to a collection that implements INotifyCollectionChanged, such as an ObservableCollection(Of T). In order to automatically reflect property changes, the objects in the source collection must implement the INotifyPropertyChanged interface.

绑定数据

  1. 设置ItemsSource属性为一个IEnumerable接口的实现(作为数据源)
  2. DataGird中的每一行都绑定到在数据源中的一个对象,每一列都绑定到数据对象中的一个属性
  3. 为了使用户接口能够在items增加或减少时能够从数据源自动更新,DataGrid必须绑定到一个INotifyCollectionChanged接口的实现集上,就像ObservableCollection(Of T)
  4. 为了自动反应属性的变化,在数据源中的对象集必须实现INotifyPropertyChanged接口。
绑定数据using System.Windows;
using System.Collections.ObjectModel;

namespace csdemo.wpf.controls.DataGrid
{
    /// <summary>
    /// DataGridWindow.xaml 的交互逻辑
    /// </summary>
    public partial class DataGridWindow : Window
    {
        public DataGridWindow()
        {
            InitializeComponent();
            dtgrdDisplay.DataContext = gridList;
        }
        ObservableCollection<GirdDataItem> gridList = new ObservableCollection<GirdDataItem>();
        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            GirdDataItem item = new GirdDataItem();
            item.id = gridList.Count + 1;
            item.item = tbItem.Text.Trim();

            gridList.Add(item);
        }

        private void btnReset_Click(object sender, RoutedEventArgs e)
        {
            gridList.Clear();
            dtgrdDisplay.ItemsSource = null;
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }

    public class GirdDataItem
    {
        private int _id;

        public int id
        {
            get { return _id; }
            set { _id = value; }
        }
        private string _item;

        public string item
        {
            get { return _item; }
            set { _item = value; }
        }
    }
}



 

Columns

By default, the DataGrid control generates columns automatically when you set the ItemsSource property. The generated columns are of type DataGridCheckBoxColumn for bound Boolean (and nullable Boolean) properties, and of type DataGridTextColumn for all other properties. If a property does not have a String or numeric value type, the generated text box columns are read-only and display the data object's ToString value.

You can prevent automatic column generation by setting the AutoGenerateColumns property to false. This is useful if you want to create and configure all columns explicitly. Alternatively, you can let the data grid generate columns, but handle the AutoGeneratingColumn event to customize columns after creation. To rearrange the display order of the columns, you can set the DisplayIndex property for individual columns. For more information, see How to: Customize Auto-Generated Columns in the DataGrid Control.

Generated columns recognize the DisplayAttribute if it is present on the source object. The DisplayAttribute.ShortName property is used to specify column header text. The DisplayAttribute.Order property is used to specify the order in which columns appear. The DisplayAttribute.AutoGenerateField property is used to specify whether the field has a column generated for it. For more information, see Using Data Annotations to Customize Data Classes.

Regardless of whether you generate columns, you can use the DataGrid.Columns collection to programmatically add, insert, remove, and change any columns in the control at run time. Alternatively, you can specify columns in XAML, in which case you should set AutoGenerateColumns to false. Creating your own columns enables you to use additional column types, such as the DataGridTemplateColumn type or custom column types. The DataGridTemplateColumn type provides an easy way to create a simple custom column. The CellTemplate and CellEditingTemplate properties enable you to specify content templates for both display and editing modes.

  1. 默认的,当你设置ItemsSource属性时,DataGird控件自动生成列。生成的列中,DataGirdCheckBoxColumn对应绑定Boolean类型的属性,DataGridTextColumn对应所有的其他类型属性。如果一个属性没有一个字符或数值型的值字段,生成的文本框是只读的,并且显示以ToString形式的数据对象。
  2. 你可以通过设置AutoGenerateColumns属性为false来阻止自动生成列。
  3. 你可以通过设置数据源对象的DisplayAttribute属性来控制生成对象的显示方式。 (这个没弄明白怎么搞……)
  4. 关于如何使用Annotation,我另写了一个文章,也是大体上是Copy的「MSDN」,并将其中我认为比较关键的地方做了粗糙翻译。「文章链接」「2012年2月20日改」
  5. 无论你是否使用自动生成列,你都可以通过使用DataGrid.Columns在运行时控制列的添加、插入、移除等。
  6. 你也可以在XAML中指定列。同时,AutoGenerateColumns属性也是在XAML中设置的。

 

Grouping, Sorting, and Filtering

To group, sort, and filter data in the DataGrid, you bind the DataGrid to an ICollectionView implementation that supports these operations. You then perform the operations on the collection view. When data is grouped in the DataGrid, you can customize the appearance of the row group headers with the RowGroupHeaderStyles property. Groups can be expanded and collapsed manually, or programmatically with the ExpandRowGroup and CollapseRowGroup methods. For more information, see How to: Group, Sort, and Filter Data in the DataGrid Control.

分组,排序,过滤

  1. 你可以绑定DataGird到一个ICollectionView的实现,以便在DataGrid中进行分组、排序、过滤

 

Editing

By default, you can edit items directly in the DataGrid. To guarantee that edits can be committed and canceled correctly, the objects in the DataGrid must implement the IEditableObject interface. Alternatively, you can set the IsReadOnly property to true to disable editing in the DataGrid.

A cell level edit is committed when you move to another cell in the same row. All edits in a row are committed when you press ENTER or move to another row. You cancel a cell edit by pressing ESC one time, and cancel all edits in a row by pressing ESC two times. For more information about programmatically committing and canceling edits, see the CommitEdit and CancelEdit methods. For more information about edit related events, see BeginningEdit, PreparingCellForEdit, CellEditEnding, CellEditEnded, RowEditEnding, and RowEditEnded.

编辑

  1. 默认情况下,可以直接在DataGrid中编辑对象。
  2. 为了保证编辑后的对象能够被正确提交,在DataGrid中的对象必须实现IEditableObject接口。你也可以指定IsReadOnly属性为true,以便关闭在DataGrid中的编辑功能。
  3. 单元格级别的编辑,在你转到同行的另一个单元格的时候,被提交。当你按下Enter键的时候,整行都被提交。你可以使用按ESC键两次来取消编辑。

Validation

The DataGrid supports cell-level property validation and row-level object validation. If a validation exception is encountered in the property setter, the cell editing control displays its error state. The DataGridCell.IsValid, DataGridRow.IsValid, and DataGrid.IsValid properties are all set to false. The DataGrid will not exit cell editing mode until the validation error is resolved.

When the row edit is committed, each cell is validated again. In addition, if the object that the row is bound to has a ValidationAttribute, validation is performed on the object. If object validation errors are found, the DataGridRow.IsValid, and DataGrid.IsValid properties are set to false The DataGrid has a built-in ValidationSummary where row-level errors are displayed. The DataGrid will not exit row editing mode until the validation errors are resolved. In order for validation to work correctly, each DataGridBoundColumn.Binding must have its ValidatesOnExceptions and NotifyOnValidationError properties set to true, and its UpdateSourceTrigger set to Explicit.

验证

  1. DataGrid支持单元格级别的属性验证和行级别的对象验证。
  2. 如果 DataGridCell.IsValid DataGridRow.IsValid DataGrid.IsValid 属性全被设置为false。
  3. 在验证出的错误没有被解决,那么就不会离开单元格的编辑状态。
  4. 如果行的编辑被提交了,每一个单元格都会被重新验证。

Paging

To page data in the DataGrid, you bind the DataGrid to an IPagedCollectionView implementation that supports paging operations. You can use a DataGrid with a DataPager control and a data source wrapped in the PagedCollectionView class to easily add paging to your DataGrid.

分页

  1. 在DataGrid上分页显示数据,你绑定DataGird到一个IPagedCollectionView接口实现来支持分页操作。
  2. 你可以配合DataGrid与DataPager控件和一个数据源覆盖到PagedColletionView类来添加分页到你的DataGrid.

 

Customizing the DataGrid Control

The DataGrid control supports common table formatting options, such as alternating row backgrounds and the ability to show or hide headers, grid lines, and scroll bars. Additionally, the control provides several style and template properties that you can use to completely change the appearance of the control and its rows, columns, headers, and cells.

To customize DataGrid behavior, you can handle events for selection change, cell editing, and column re-ordering. The DataGrid also exposes several events for row recycling that you can handle to further customize rows. For more information, see Walkthrough: Customizing the DataGrid Control Using Properties.

To apply the same property settings to multiple DataGrid controls, use the Style property. To change the visual structure and visual behavior of a DataGrid, copy and modify its default style and template. For more information, see Control Customization.

Dependency properties for this control might be set by the default style of the control. If a dependency property for a DataGrid is set by its default style, the property might change from its default value when the DataGrid appears in the application. For more information, see Dependency Property Value Precedence. You can get the default style and template for DataGrid from DataGrid Styles and Templates.

定制DataGrid控件

  1. http://msdn.microsoft.com/en-us/library/cc903951(v=vs.95).aspx

 

XAML<!-- NOTE: 
  By convention, the sdk prefix indicates a URI-based XAML namespace declaration 
  for Silverlight SDK client libraries. This namespace declaration is valid for 
  Silverlight 4 only. In Silverlight 3, you must use individual XAML namespace 
  declarations for each CLR assembly and namespace combination outside the scope 
  of the default Silverlight XAML namespace. For more information, see the help 
  topic "Prefixes and Mappings for Silverlight Libraries". 
-->
<UserControl x:Class="DataGridSnippets.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
    <ScrollViewer VerticalScrollBarVisibility="Auto" BorderThickness="0" Padding="0">
    <StackPanel Margin="10,10,10,10">

        <TextBlock Text="DataGrid with autogenerated columns:"/>
        <sdk:DataGrid x:Name="dataGrid1" 
            Height="140" Margin="0,5,0,10"
            AutoGenerateColumns="True" />            

        <TextBlock Text="DataGrid with row details sections:"/>
        <sdk:DataGrid x:Name="dataGrid3" 
            Height="140" Margin="0,5,0,10"
            RowDetailsVisibilityMode="VisibleWhenSelected" >            
            <sdk:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="12" Text="Address: " />
                        <TextBlock FontSize="12" Text="{Binding Address}"/>
                    </StackPanel>
                </DataTemplate>
            </sdk:DataGrid.RowDetailsTemplate>                
        </sdk:DataGrid>

        <TextBlock Text="DataGrid with configured columns:"/>
        <sdk:DataGrid x:Name="dataGrid4" 
            Height="160" Margin="0,5,0,10" 
            RowHeight="40" AutoGenerateColumns="False" >    
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn 
                    Header="First Name" 
                    Width="SizeToHeader"
                    Binding="{Binding FirstName}" 
                    FontSize="20" />
                <sdk:DataGridTextColumn 
                    Header="Last Name" 
                    Width="SizeToCells"
                    Binding="{Binding LastName}" 
                    FontSize="20" />
                <sdk:DataGridTextColumn 
                    Header="Address"
                    Width="150"
                    Binding="{Binding Address}" >
                    <sdk:DataGridTextColumn.ElementStyle>
                        <Style TargetType="TextBlock">
                            <Setter Property="TextWrapping" Value="Wrap"/>
                        </Style>
                    </sdk:DataGridTextColumn.ElementStyle>
                    <sdk:DataGridTextColumn.EditingElementStyle>
                        <Style TargetType="TextBox">
                            <Setter Property="Foreground" Value="Blue"/>
                        </Style>
                    </sdk:DataGridTextColumn.EditingElementStyle>
                </sdk:DataGridTextColumn>
                <sdk:DataGridCheckBoxColumn 
                    Header="New?" 
                    Width="40"
                    Binding="{Binding IsNew}" />
                <sdk:DataGridCheckBoxColumn 
                    Header="Subscribed?" 
                    Width="Auto"
                    Binding="{Binding IsSubscribed}" 
                    IsThreeState="True" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>

        <TextBlock Text="DataGrid with template column and custom alternating row backgrounds:"/>
        <sdk:DataGrid x:Name="dataGrid5" 
            Height="125" Margin="0,5,0,10"
            AutoGenerateColumns="False"
            RowBackground="Azure"
            AlternatingRowBackground="LightSteelBlue">
            <sdk:DataGrid.Columns>
                <!-- Name Column -->
                <sdk:DataGridTemplateColumn Header="Name">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                                <TextBlock Padding="5,0,5,0"
                                    Text="{Binding FirstName}"/>
                                <TextBlock Text="{Binding LastName}"/>
                            </StackPanel>
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate> 
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBox Text="{Binding FirstName}" BorderThickness="0"/>
                                <TextBox Text="{Binding LastName}" BorderThickness="0"/>
                            </StackPanel>
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate> 
                </sdk:DataGridTemplateColumn>              
                <!-- Address Column -->
                <sdk:DataGridTextColumn
                    Header="Address" Width="300"
                    Binding="{Binding Address}" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
    </StackPanel>
    </ScrollViewer>
</UserControl>

C#using System;
using System.Collections.Generic;
using System.Windows.Controls;

namespace DataGridSnippets
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            // Set the ItemsSource to autogenerate the columns.
            dataGrid1.ItemsSource = Customer.GetSampleCustomerList();
            dataGrid3.ItemsSource = Customer.GetSampleCustomerList();
            dataGrid4.ItemsSource = Customer.GetSampleCustomerList();
            dataGrid5.ItemsSource = Customer.GetSampleCustomerList();
        }
    }

    public class Customer
    {
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Address { get; set; }
        public Boolean IsNew { get; set; }

        // A null value for IsSubscribed can indicate 
        // "no preference" or "no response".
        public Boolean? IsSubscribed { get; set; }

        public Customer(String firstName, String lastName, 
            String address, Boolean isNew, Boolean? isSubscribed)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Address = address;
            this.IsNew = isNew; 
            this.IsSubscribed = isSubscribed;
        }

        public static List<Customer> GetSampleCustomerList()
        {
            return new List<Customer>(new Customer[4] {
                new Customer("A.", "Zero", 
                    "12 North Third Street, Apartment 45", 
                    false, true), 
                new Customer("B.", "One", 
                    "34 West Fifth Street, Apartment 67", 
                    false, false),
                new Customer("C.", "Two", 
                    "56 East Seventh Street, Apartment 89", 
                    true, null),
                new Customer("D.", "Three", 
                    "78 South Ninth Street, Apartment 10", 
                    true, true)
            });
        }
    }
}

转载于:https://my.oschina.net/skyler/blog/706117