WPF之DataGrid--列的前台及后台實現


一、前台實現

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

四、源碼

DataGrid示例


免責聲明!

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



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