转载

WPF之DataGrid列的前台与后台实现

一、前台实现

在xaml里可以很轻松地实现一个如下图所示的DataGrid

WPF之DataGrid列的前台与后台实现

<StackPanel>  <ComboBox Width="50" HorizontalAlignment="Left" SelectionChanged="ComboBox_SelectionChanged_1">   <ComboBoxItem Content="全部"></ComboBoxItem>   <ComboBoxItem Content="男"></ComboBoxItem>   <ComboBoxItem Content="女"></ComboBoxItem>  </ComboBox>  <DataGrid Name="dataGrid" AutoGenerateColumns="False" CanUserAddRows="False">   <DataGrid.Columns>    <DataGridCheckBoxColumn>     <DataGridCheckBoxColumn.Header>      <CheckBox Click="CheckBox_Click_1"></CheckBox>     </DataGridCheckBoxColumn.Header>    </DataGridCheckBoxColumn>    <DataGridTemplateColumn>     <DataGridTemplateColumn.CellTemplate>      <DataTemplate>       <Ellipse Height="10" Width="10" Fill="{Binding FillColor}"></Ellipse>      </DataTemplate>     </DataGridTemplateColumn.CellTemplate>    </DataGridTemplateColumn>    <DataGridTextColumn Header="姓名" Width="100" Binding="{Binding Name}"></DataGridTextColumn>    <DataGridTemplateColumn Header="性别" Width="100">     <DataGridTemplateColumn.CellTemplate>      <DataTemplate>       <StackPanel Orientation="Horizontal">        <RadioButton Content="男" IsChecked="{Binding IsBoy}" Margin="5"></RadioButton>        <RadioButton Content="女" IsChecked="{Binding IsGirl}" Margin="5"></RadioButton>       </StackPanel>      </DataTemplate>     </DataGridTemplateColumn.CellTemplate>    </DataGridTemplateColumn>    <DataGridTemplateColumn Header="住址" Width="200">     <DataGridTemplateColumn.CellTemplate>      <DataTemplate>       <Grid Name="address">        <Grid.ColumnDefinitions>         <ColumnDefinition Width="5*"></ColumnDefinition>         <ColumnDefinition Width="1*"></ColumnDefinition>        </Grid.ColumnDefinitions>        <TextBox Text="{Binding Address}" Grid.Column="0"></TextBox>        <Button Content="Csl" Grid.Column="1" Click="Button_Click_1"          Template="{StaticResource ButtonStyle}"></Button>       </Grid>      </DataTemplate>     </DataGridTemplateColumn.CellTemplate>    </DataGridTemplateColumn>   </DataGrid.Columns>  </DataGrid>  <Button Content="修改选中行的姓名" Template="{StaticResource ButtonStyle}"    Width="72" Height="23" Click="Button_Click_2"></Button> </StackPanel> 

二、几个主要的事件代码

1、CheckBox全选、反选:

/// <summary> /// 全选、反选 /// </summary> /// <param name="value"></param> private void ChangeIsChecked(bool value) {  for (int i = 0; i < this.dataGrid.Items.Count; i++)  {   DataGridRow row = (DataGridRow)this.dataGrid.ItemContainerGenerator.ContainerFromIndex(i);   if (row != null)   {    FrameworkElement fe = this.dataGrid.Columns[0].GetCellContent(row);    if (fe != null)    {     CheckBox chk = fe as CheckBox;     if (chk.IsChecked.Value == !value)     {      chk.IsChecked = value;     }    }   }  } } 
2、ComboBox筛选:
private ICollectionView view; /// <summary> /// 筛选 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ComboBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e) {  this.view = CollectionViewSource.GetDefaultView(this.students);  switch ((sender as ComboBox).SelectedIndex)  {    case 0:    this.view.Filter = x => true;    break;   case 1:    this.view.Filter = x => (x as Student).IsBoy;    break;   case 2:    this.view.Filter = x => (x as Student).IsGirl;    break;   default:    break;  } } 

3、修改单元格内容:

private void Button_Click_1(object sender, RoutedEventArgs e) {  //获取指定的列  DataGridTemplateColumn column = this.dataGrid.Columns[4] as DataGridTemplateColumn;  //获取指定的行与列相交位置的单元格  FrameworkElement element = column.GetCellContent(this.dataGrid.Items[this.dataGrid.SelectedIndex]);  Grid grid = column.CellTemplate.FindName("address", element) as Grid;  if (grid != null)  {   TextBox textBox = grid.Children[0] as TextBox;   MessageBox.Show(textBox.Text);  } } 

三、后台实现

上图所示的DataGrid通过后台实现相对要复杂一些,如果某一列在其单元格中承载的是模板,那么其创建的流程为:

1、创建模板FrameworkElementFactory;

2、设置模板的依赖项属性及数据绑定,添加子项;

3、把模板赋给DataTemplate.VisualTree;

4、把DataTemplate赋给DataGridTemplateColumn.CellTemplate;

5、把DataGridTemplateColumn添加到DataGrid.Columns

/// <summary> /// 生成地址列 /// </summary> private void CreateColumnAddress() {  DataGridTemplateColumn column = new DataGridTemplateColumn()  {   Header = "住址",   Width = 200.0  };  DataTemplate temp = new DataTemplate();  //生成Grid  FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));  grid.Name = "address";  //生成ColumnDefinition  FrameworkElementFactory c1 = new FrameworkElementFactory(typeof(ColumnDefinition));  FrameworkElementFactory c2 = new FrameworkElementFactory(typeof(ColumnDefinition));  c1.SetValue(ColumnDefinition.WidthProperty, new GridLength(5, GridUnitType.Star));  c2.SetValue(ColumnDefinition.WidthProperty, new GridLength(1, GridUnitType.Star));  grid.AppendChild(c1);  grid.AppendChild(c2);  //生成TextBox  FrameworkElementFactory textBox = new FrameworkElementFactory(typeof(TextBox));  Binding binding = new Binding("Address");  textBox.SetBinding(TextBox.TextProperty, binding);  textBox.SetValue(Grid.ColumnProperty, 0);  //生成Button  FrameworkElementFactory button = new FrameworkElementFactory(typeof(Button));  button.SetValue(Button.ContentProperty, "Cls");  button.SetValue(Grid.ColumnProperty, 1);  button.SetValue(Button.TemplateProperty, this.FindResource("ButtonStyle"));  button.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click_1));  grid.AppendChild(textBox);  grid.AppendChild(button);  temp.VisualTree = grid;  column.CellTemplate = temp;  this.dataGrid.Columns.Add(column); } 

四、源码

DataGrid示例

正文到此结束
Loading...