一、前台實現
在xaml里可以很輕松地實現一個如下圖所示的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); } }
三、后台實現
一般用於動態生成Column,其實現過程相對要復雜一些。如果某一列在其單元格中承載的是模板,那么其創建的流程為:
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); }
四、源碼