WebEnh

.net7 mvc jquery bootstrap json 学习中 第一次学PHP,正在研究中。自学进行时... ... 我的博客 https://enhweb.github.io/ 不错的皮肤:darkgreentrip,iMetro_HD
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WPF DataGrid使用 自动显示行号、全选、三级联动、拖拽

Posted on 2024-05-27 22:02  WebEnh  阅读(522)  评论(0编辑  收藏  举报

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());
        }