WPF DataGrid使用 自動顯示行號、全選、三級聯動、拖拽


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

View Code
 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新建一行,並為需要的單元格提供默認值

View Code
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

View Code
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

View Code
 <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)后台事件

View Code
 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)刪除按鈕事件

View Code
        //刪除按鈕事件
        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)業務實體

View Code
  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)前台界面

View Code
  <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)后台邏輯

View Code
 int rowIndex = -1;
        private void dgTool_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            rowIndex = ((System.Windows.Controls.DataGrid)((sender))).SelectedIndex;
        }

      處理省邏輯

View Code
 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;
        }

  處理市邏輯

View Code
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;
        }

  處理縣邏輯

View Code
 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的拖拽

 

總結:以上純屬個人的理解,對於有些地方覺得還是理解不是很深,有不足之處和錯誤的地方希望大家幫我指出。謝謝

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM