WPF篇(18)-DataGrid数据表格控件+ComboBox下拉框控件

DataGrid数据表格控件

DataGrid是一个可以多选的数据表格控件。所以,它继承一个支持多选的父类——MultiSelector。

public abstract class MultiSelector : Selector
{
    protected MultiSelector();
 
    public IList SelectedItems { get; }
    protected bool CanSelectMultipleItems { get; set; }
    protected bool IsUpdatingSelectedItems { get; }
 
    public void SelectAll();
    public void UnselectAll();
    protected void BeginUpdateSelectedItems();
    protected void EndUpdateSelectedItems();
 
}

从上面的定义来看,DataGrid多选的结果会保存在SelectedItems 只读属性中,CanSelectMultipleItems 属性用来设置是否开启多选。

1. DataGrid属性分析

DataGrid提供了大量的依赖属性,合理充分利用这些属性,在开发ERP、CMS、报表等软件时可达到事半功倍的效果。这里我给大家只列出常用的和重要的,如果有想了解所有属性的,可以参考官网。

  • RowHeaderTemplate:获取或设置行标题的模板。(重要)
  • CanUserAddRows:是否可以添加新行。 (重要)
  • CurrentItem:当前选中行(一般指绑定的数据源的某一个元素。)(常用)
  • CanUserDeleteRows:是否可以删除行。 (重要)
  • RowHeaderStyle:获取或设置应用于所有行标题的样式。 (重要)
  • IsReadOnly:当前控件是否只读。(常用)
  • ColumnHeaderStyle:获取或设置所有列标题的样式。 (重要)
  • RowStyle:获取或设置应用到的所有行的样式。 (重要)
  • AlternatingRowBackground:获取或设置交替行上使用的背景画笔。 (重要)
  • VerticalGridLinesBrush:获取或设置用于绘制垂直网格线的画笔。 (常用)
  • Columns:获取一个集合中的所有列。 (常用)
  • CellStyle:获取或设置所有单元格的样式。 (常用)
  • FrozenColumnCount: 获取或设置非滚动列的数量。 (常用)
  • AutoGenerateColumns:获取或设置一个值,该值指示是否自动创建列。 (常用)
  • CanUserSortColumns:是否可以单击列标题来对列排序。 (常用)
  • SelectionMode:是否支持多选 。(重要)

在上述,Columns属性是DataGrid最基本的一个属性。它是一个ObservableCollection<DataGridColumn>类型的集合,表示DataGrid的列的集合。其实DataGridColumn只是一个抽象基类,我们真正在实例化时,是实例化DataGridColumn的子类,然后放到Columns属性中。

事件成员

  • Sorting 对列进行排序时发生。
  • AutoGeneratedColumns: 所有列的自动生成完成后发生。
  • AutoGeneratingColumn: 自动生成单独的列时出现。
  • ColumnHeaderDragDelta:每次鼠标位置发生更改时在用户拖动列标题时发生。
  • ColumnHeaderDragStarted: 当用户开始使用鼠标拖动列标题时发生。
  • ColumnHeaderDragCompleted: 当用户使用鼠标拖动后释放列标题时发生。
  • SelectedCellsChanged: 发生时 DataGrid.SelectedCells 集合更改。
  • ColumnReordering:在列移至的显示顺序中的新位置之前发生。
  • RowDetailsVisibilityChanged:当某一行的可见性详细信息元素更改时发生。
  • UnloadingRow:发生时 DataGridRow 对象将成为可供重用。
  • LoadingRowDetails:新的行的详细信息模板应用于行时发生。
  • InitializingNewItem:创建一个新项时出现。
  • PreparingCellForEdit:在单元格进入编辑模式时发生。
  • BeginningEdit:发生行或单元格进入编辑模式之前。
  • CurrentCellChanged:在 DataGrid.CurrentCell 属性的值更改后发生。
  • CellEditEnding:在单元格的编辑将在提交或取消前发生。
  • RowEditEnding:在提交或取消行编辑之前发生。
  • LoadingRow: 加载row时。
  • ColumnDisplayIndexChanged: 其中一个列更改属性时。
  • UnloadingRowDetails:行详细信息元素成为可供重用时发生。
  • AddingNewItem: 新项添加到DataGrid之前发生
  • CopyingRowClipboardContent: 默认行内容准备好之后发生。
  • ColumnReordered: 在列移至的显示顺序中的新位置时发生。

代码示例

前端代码

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>
        <DataGrid x:Name="datagrid" 
                  SelectionMode="Extended"
                  IsReadOnly="True" 
                  SelectionChanged="datagrid_Selected">
            <DataGrid.Columns>
                <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
                <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
                <DataGridTextColumn Header="地址" Binding="{Binding Address}" />
            </DataGrid.Columns>
        </DataGrid>
        
        <StackPanel Grid.Column="1">
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="姓名:"/>
                <TextBlock x:Name="_TextBlockName"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="年龄:"/>
                <TextBlock x:Name="_TextBlockAge"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="地址:"/>
                <TextBlock x:Name="_TextBlockAddress"/>
            </StackPanel>
        </StackPanel>
    </Grid>

后端代码

 public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
 
    }
 
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            datagrid.Items.Add(new Person { Name = "张三", Age = 22, Address = "广东省廉江市车板镇大坝村" });
            datagrid.Items.Add(new Person { Name = "李四", Age = 23, Address = "江西省景德镇市市辖区" });
            datagrid.Items.Add(new Person { Name = "王五", Age = 24, Address = "上海市虹口区" });
        }
 
        private void datagrid_Selected(object sender, RoutedEventArgs e)
        {
            DataGrid datagrid = sender as DataGrid;
            if (datagrid == null) return;
 
            var person = datagrid.SelectedItem as Person;
            if (person == null) return;
 
            _TextBlockName.Text = person.Name;
            _TextBlockAge.Text = person.Age + "岁";
            _TextBlockAddress.Text = person.Address;
        }
    }

在这里插入图片描述
在这个例子中,我们尽量还原了与ListView控件一致的功能, 需要注意的是:我们将DataGrid的IsReadOnly="True",这是因为我们直接将数据元素一条一条的加入到DataGrid的Items属性中,而Items属性本身是一个只读属性,不支持写入。这样的话,当鼠标双击时会报错。

如果要解决这个问题,这就要用到ItemsControl基类中的ItemsSource数据源属性。

我们需要采用DataGrid另外一种赋值方式——数据源赋值。即把一个集合绑定到该属性上,这样在前端就可以编辑数据源,从而不会引发报错。

后端修改

List<Person> list = new List<Person>();
 
list.Add(new Person { Name = "张三", Age = 22, Address = "广东省廉江市车板镇大坝村" });
list.Add(new Person { Name = "李四", Age = 23, Address = "江西省景德镇市市辖区" });
list.Add(new Person { Name = "王五", Age = 24, Address = "上海市虹口区" });
 
datagrid.ItemsSource = list;

前端修改
AutoGenerateColumns属性设为不可自动创建列。

<DataGrid x:Name="datagrid" 
          SelectionMode="Extended"
          IsReadOnly="False"
          AutoGenerateColumns="False"
          SelectionChanged="datagrid_Selected">
    <DataGrid.Columns>
        <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
        <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
        <DataGridTextColumn Header="地址" Binding="{Binding Address}" />
    </DataGrid.Columns>
</DataGrid>

ComboBox下拉框控件

ComboBox表示带有下拉列表的控件,实际上可以把它看成两个部分组成,一个类似TextBox文本输入框,所以它有一个Text文本属性,用于获取ComboBox框的文本值,另一个是类似ListBox的列表框,用于显示ComboBox绑定的所有数据源。

ComboBox继承于Selector,所以,它只能是单选操作。

属性成员

  • ShouldPreserveUserEnteredPrefix:是否保留用户的输入,或者输入替换匹配项。
  • IsEditable:是否启用或禁用编辑文本框中文本
  • Text:获取或设置当前选定项的文本。
  • IsReadOnly:文本内容是否只读
  • SelectionBoxItem:获取在选择框中显示的项。
  • MaxDropDownHeight:获取或设置一个组合框下拉列表的最大高度。
  • SelectionBoxItemStringFormat:指定选择框中文本的显示格式。
  • StaysOpenOnEdit:在编辑输入框文本时,希望下拉框保持打开,则为true。
  • IsSelectionBoxHighlighted:是否突出显示SelectionBoxItem。
  • IsDropDownOpen:是否打开组合框下拉列表。
  • SelectionBoxItemTemplate:获取选择框内容的项模板。

ComboBox示例

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>
        <StackPanel>
            <ComboBox x:Name="combobox1" IsEditable="True"  Height="30" Margin="20,10" 
                      TextBoxBase.TextChanged="combobox1_TextChanged"/>
            <ComboBox x:Name="combobox2" StaysOpenOnEdit="True" VerticalAlignment="Top" 
                      SelectionChanged="combobox2_SelectionChanged"
                      Height="30" Margin="20,10" DisplayMemberPath="Name">
            </ComboBox>
        </StackPanel>
        
        
        <StackPanel Grid.Column="1">
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="电话:"/>
                <TextBlock x:Name="_TextBlockTel"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="姓名:"/>
                <TextBlock x:Name="_TextBlockName"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="年龄:"/>
                <TextBlock x:Name="_TextBlockAge"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="地址:"/>
                <TextBlock x:Name="_TextBlockAddress"/>
            </StackPanel>
        </StackPanel>
    </Grid>

后端代码

namespace WpfTest01
{
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
 
    }
 
    public partial class MainWindow : Window
    {        
        public MainWindow()
        {
            InitializeComponent();
 
            List<Person> list = new List<Person>();
 
            list.Add(new Person { Name = "张三", Age = 22, Address = "广东省廉江市车板镇大坝村" });
            list.Add(new Person { Name = "李四", Age = 23, Address = "江西省景德镇市市辖区" });
            list.Add(new Person { Name = "王五", Age = 24, Address = "上海市虹口区" });
 
            combobox2.ItemsSource = list;
        }
 
        private void combobox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            _TextBlockTel.Text = combobox1.Text;
        }
 
        private void combobox2_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox combobox = sender as ComboBox;
            if (combobox == null) return;
 
            var person = combobox.SelectedItem as Person;
            if (person == null) return;
 
            _TextBlockName.Text = person.Name;
            _TextBlockAge.Text = person.Age + "岁";
            _TextBlockAddress.Text = person.Address;
        }
    }
}

在这里插入图片描述

我们在xaml中实例化了两个ComboBox,第一个直接当成了TextBox来使用;第二个则绑定了一个数据源,并在Xaml中指定了DisplayMemberPath属性显示Person的Name,最后在后端代码中,依然使用SelectedItem 属性获取当前选中项,转化成Person,以获取实际的选中数据。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术闲聊DD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值