1.DataGrid的使用自動顯示行號(修復刪除行時行號顯示不正確)

dgTool.LoadingRow += new EventHandler<DataGridRowEventArgs>(dgTool_LoadingRow); dgTool.UnloadingRow +=new EventHandler<DataGridRowEventArgs>(dgTool_UnloadingRow); void dgTool_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.Header = e.Row.GetIndex() + 1; } void dgTool_UnloadingRow(object sender, DataGridRowEventArgs e) { dgTool_LoadingRow(sender, e); if (dgTool.Items != null) { for (int i = 0; i < dgTool.Items.Count; i++) { try { DataGridRow row = dgTool.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow; if (row != null) { row.Header = (i + 1).ToString(); } } catch { } } } }
2.DataGrid新建一行,並為需要的單元格提供默認值

dgTool.InitializingNewItem += new InitializingNewItemEventHandler(dgTool_InitializingNewItem); dgTool.RowEditEnding += new EventHandler<DataGridRowEditEndingEventArgs>(dgTool_RowEditEnding); private void dgTool_InitializingNewItem(object sender, InitializingNewItemEventArgs e) { //這里的實體為你綁定數據源中的實體類型 EntityType newItem = e.NewItem as EntityType; newItem.ID = dgTool.Items.Count - 2; } //這里是為了解決添加完成一行數據之后,行號顯示不正確(當然還可以做其他操作) void dgTool_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) { if (dgTool.Items != null) { for (int i = 0; i < dgTool.Items.Count; i++) { try { DataGridRow row = dgTool.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow; if (row != null) { row.Header = (i + 1).ToString(); } } catch { } } } }
3.DataGrid實現全選和單選
1)DataGrid綁定數據實體類Entity

public class Entity : INotifyPropertyChanged { //標記是否刪除 private bool isChecked = false; public bool IsChecked { get { return isChecked; } set { isChecked = value; NotifyPropertyChanged("IsChecked"); } } //序號 private int id = 0; public int ID { get { return id; } set { id = value; NotifyPropertyChanged("ID"); } } public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
2)前台界面XAML

<DataGrid x:Name="dgTool" Grid.Row="2" SelectionChanged="dgTool_SelectionChanged" RowHeaderWidth="50" FontFamily="Microsoft YaHei" FontSize="16" FontWeight="Normal" SelectionMode="Single" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True" IsReadOnly="False" CanUserSortColumns="False" AlternatingRowBackground="LightGray"> <DataGrid.ColumnHeaderStyle> <Style TargetType="DataGridColumnHeader"> <Setter Property="HorizontalContentAlignment" Value="Center"> </Setter> </Style> </DataGrid.ColumnHeaderStyle> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.Header> <CheckBox Name="selectAll_checkBox" Content="全選" IsThreeState="True" HorizontalAlignment="Center" Click="selectAll_checkBox_Click" /> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox Name="select_checkBox" IsChecked="{Binding Path=IsChecked}" Click="select_checkBox_Click"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="ID" Width="*" Binding="{Binding Path=ID}"/> </DataGrid.Columns> </DataGrid>
3)后台事件

int count = 0; private void select_checkBox_Click(object sender, RoutedEventArgs e) { //因為我前台做的是單項綁定,所有要手動修改數據源IsChecked屬性,因為我要統計勾選的個數 //做成雙向綁定的話(將IsChecked="{Binding Path=IsChecked}" 改成 IsChecked="{Binding Path=IsChecked,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"即可),就不需要手動修改IsChecked屬性了,但還是要統計個數 var item = dgTool.SelectedItem; if (item != null) { Entity entity = item as Entity; if (entity == null) return; if ((bool)((System.Windows.Controls.Primitives.ToggleButton)(sender)).IsChecked) { entity.IsChecked = true; count++; } else { entity.IsChecked = false; count--; } //根據勾選的個數,改變列頭的狀態 全選、全不選、部分選 CheckBox cb = this.FindName("selectAll_checkBox") as CheckBox; cb.IsThreeState = true; if (cb != null) { if (count == 0) cb.IsChecked = false; List<Entity> source = dgTool.ItemsSource as List<Entity>; if (source != null) { if (count == source.Count) cb.IsChecked = true; else cb.IsChecked = null; } } } } private void selectAll_checkBox_Click(object sender, RoutedEventArgs e) { List<Entity> source = dgTool.ItemsSource as List<Entity>; if (source == null) return; bool? isThreeStatus = ((System.Windows.Controls.Primitives.ToggleButton)(sender)).IsChecked; if (isThreeStatus == null) return; if ((bool)isThreeStatus) { foreach (Entity each in source) { each.IsChecked = true; } count = source.Count; } else { foreach (Entity each in source) { each.IsChecked = false; } count = 0; } }
4)刪除按鈕事件

//刪除按鈕事件 private void btnDelRows_Click(object sender, RoutedEventArgs e) { List<Entity> source = dgTool.ItemsSource as List<Entity>; if (source == null) return; int count = 0; for (int i = 0; i < source.Count; i++) { Entity temp = source[i]; if (temp.IsChecked) { source.Remove(temp); //因為刪除導致后面的項成為當前項 i--; //所有索引應該不變,由於后面i會加1,先減一 count++; } } if (count == 0) MessageBox.Show("請選擇要刪除的行"); else { MessageBox.Show("共刪除" + count + "條記錄"); } dgTool.Items.Refresh(); //對DataGrid刷新數據 如果DataGrid中添加了排序則只能用下面的進行刷新 ICollectionView dataView = CollectionViewSource.GetDefaultView(dgTool.ItemsSource); dataView.SortDescriptions.Add(new SortDescription("ID", ListSortDirection.Ascending)); dataView.Refresh(); }
4.三級聯動
1)業務實體

public class Entity : INotifyPropertyChanged { //標記是否刪除 private bool isChecked = false; public bool IsChecked { get { return isChecked; } set { isChecked = value; NotifyPropertyChanged("IsChecked"); } } //序號 private int id = 0; public int ID { get { return id; } set { id = value; NotifyPropertyChanged("ID"); } } //省 private int provinceNo = 0; public int ProvinceNo { get { return provinceNo; } set { provinceNo = value; NotifyPropertyChanged("ProvinceNo"); } } private string provinceName = string.Empty; public string ProvinceName { get { return provinceName; } set { provinceName = value; NotifyPropertyChanged("ProvinceName"); } } //市 private int cityNo = 0; public int CityNo { get { return cityNo; } set { cityNo = value; NotifyPropertyChanged("CityNo"); } } private string cityName = string.Empty; public string CityName { get { return cityName; } set { cityName = value; NotifyPropertyChanged("CityName"); } } //縣 private int countyNo = 0; public int CountyNo { get { return countyNo; } set { countyNo = value; NotifyPropertyChanged("CountyNo"); } } private string countyName = string.Empty; public string CountyName { get { return countyName; } set { countyName = value; NotifyPropertyChanged("CountyName"); } } public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
2)前台界面

<DataGrid x:Name="dgTool" Grid.Row="2" SelectionChanged="dgTool_SelectionChanged" RowHeaderWidth="50" FontFamily="Microsoft YaHei" FontSize="16" FontWeight="Normal" SelectionMode="Single" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True" IsReadOnly="False" CanUserSortColumns="False" AlternatingRowBackground="LightGray" > <DataGrid.ColumnHeaderStyle> <Style TargetType="DataGridColumnHeader"> <Setter Property="HorizontalContentAlignment" Value="Center"> </Setter> </Style> </DataGrid.ColumnHeaderStyle> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.Header> <CheckBox Name="selectAll_checkBox" Content="全選" IsThreeState="True" HorizontalAlignment="Center" Click="selectAll_checkBox_Click" /> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox Name="select_checkBox" IsChecked="{Binding Path=IsChecked,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Click="select_checkBox_Click"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="ID" Width="*" Binding="{Binding Path=ID}"/> <!--<DataGridComboBoxColumn x:Name="cbbProvinceName" Header="省" Width="*" TextBinding="{Binding Path=ProvinceName}" />--> <DataGridTemplateColumn Header="省" Width="*"> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox x:Name="cbbProvinceName" Text="{Binding Path=ProvinceName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="False" Loaded="cbbProvinceName_Loaded" SelectionChanged="cbbProvinceName_SelectionChanged" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=ProvinceName, Mode=OneWay}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="市" Width="*"> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox x:Name="cbbCityName" Text="{Binding Path=CityName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="False" Loaded="cbbCityName_Loaded" SelectionChanged="cbbCityName_SelectionChanged"> </ComboBox> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=CityName, Mode=OneWay}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="縣" Width="*"> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox x:Name="cbbCountyName" Text="{Binding Path=CountyName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="False" Loaded="cbbCountyName_Loaded" SelectionChanged="cbbCountyName_SelectionChanged" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=CountyName}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
3)后台邏輯

int rowIndex = -1; private void dgTool_SelectionChanged(object sender, SelectionChangedEventArgs e) { rowIndex = ((System.Windows.Controls.DataGrid)((sender))).SelectedIndex; }
處理省邏輯

private void cbbProvinceName_Loaded(object sender, RoutedEventArgs e) { var cbbProvinceNam = sender as ComboBox; cbbProvinceNam.ItemsSource = provinceSource; cbbProvinceNam.SelectedValuePath = "ProvinceNo"; cbbProvinceNam.DisplayMemberPath = "ProvinceName"; } private void cbbProvinceName_SelectionChanged(object sender, SelectionChangedEventArgs e) { var cbbProvinceName = sender as ComboBox; var rowData = source.ElementAt(rowIndex); if (cbbProvinceName != null && cbbProvinceName.SelectedValue != null) { rowData.ProvinceNo = int.Parse(cbbProvinceName.SelectedValue.ToString()); } rowData.CityNo = -1; rowData.CityName = string.Empty; rowData.CountyNo = -1; rowData.CountyName = string.Empty; }
處理市邏輯

private void cbbCityName_Loaded(object sender, RoutedEventArgs e) { var cbbCityName = sender as ComboBox; var rowData = source.ElementAt(rowIndex); if (rowData != null) { if (String.IsNullOrEmpty(rowData.ProvinceName)) { MessageBox.Show("請先選擇省"); e.Handled = true; return; } else { cbbCityName.ItemsSource = citySource; cbbCityName.SelectedValuePath = "CityNo"; cbbCityName.DisplayMemberPath = "CityName"; } } } private void cbbCityName_SelectionChanged(object sender, SelectionChangedEventArgs e) { var rowData = source.ElementAt(rowIndex); rowData.CountyName = string.Empty; rowData.CountyNo = -1; }
處理縣邏輯

private void cbbCountyName_Loaded(object sender, RoutedEventArgs e) { var cbbCountyName = sender as ComboBox; var rowData = source.ElementAt(rowIndex); if (rowData != null) { e.Handled = true; return; } if (String.IsNullOrEmpty(rowData.ProvinceName)) { MessageBox.Show("請先選擇省"); e.Handled = true; return; } else { if (string.IsNullOrEmpty(rowData.CityName)) { MessageBox.Show("請先選擇市"); e.Handled = true; return; } else { cbbCountyName.ItemsSource = countySource; cbbCountyName.DisplayMemberPath = "CountyName"; cbbCountyName.SelectedValuePath = "CountyNo"; } } } private void cbbCountyName_SelectionChanged(object sender, SelectionChangedEventArgs e) { var cbbCountyName = sender as ComboBox; var rowData = source.ElementAt(rowIndex); if (cbbCountyName != null && cbbCountyName.SelectedValue != null) rowData.CountyNo = int.Parse(cbbCountyName.SelectedValue.ToString()); }
5.DataGrid的拖拽
總結:以上純屬個人的理解,對於有些地方覺得還是理解不是很深,有不足之處和錯誤的地方希望大家幫我指出。謝謝