为自动生成的列datagrid中的每个复选框注册已检查的事件处理程序

时间:2018-05-08 02:40:57

标签: c# wpf datagrid event-handling

我的最终目标是使用自动生成的列构建数据网格(因为我永远不知道需要生成多少个类属性)。此数据网格将始终将第一列作为复选框。如果用户在数据网格中选择多行,然后选中其中一个复选框,则还将检查所有复选框(在第一列或关联列中 - 都可以)。

我已尝试在xaml中使用DataGrid.RowHeaderTemplate,如下所示:

 <DataGrid x:Name="SheetListGrid"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  HeadersVisibility="All"
                  AutoGenerateColumns="True"
                  CanUserResizeRows="False"
                  AlternatingRowBackground="LightGray"
                  AutoGeneratingColumn="SheetListGrid_AutoGeneratingColumn">

            <DataGrid.RowHeaderTemplate>
                <DataTemplate>
                    <Grid>
                        <CheckBox Checked="CheckBox_Checked"
                                  IsChecked="{Binding Path=Selected, Mode=TwoWay}"/>
                    </Grid>
                </DataTemplate>
            </DataGrid.RowHeaderTemplate>
        </DataGrid>

但我无法获得多个复选框以立即切换到选中状态。 我的第二次尝试是完全删除DataGrid.RowHeaderTemplate,并将其放在DataGrid AutoGeneratingColumn事件处理程序中,如下所示: 编辑:这个的主要目的是添加我自己的复选框列,并能够单击复选框状态。

  private void SheetListGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.Column is DataGridCheckBoxColumn && !e.Column.IsReadOnly)
        {
            FrameworkElementFactory checkboxFactory = new FrameworkElementFactory(typeof(CheckBox));
            checkboxFactory.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
            checkboxFactory.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
            checkboxFactory.SetBinding(ToggleButton.IsCheckedProperty, new Binding(e.PropertyName) { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });

            e.Column = new DataGridTemplateColumn
            {
                Header = e.Column.Header,
                CellTemplate = new DataTemplate { VisualTree = checkboxFactory },
                SortMemberPath = e.Column.SortMemberPath
            };

            // notice I tried registering the event handler here as well.
            // but this caused a continuous loop of CheckBox_Checked to be 
            // fired.
            // register the checkbox event handler
            //checkboxFactory.AddHandler(CheckBox.CheckedEvent, new RoutedEventHandler(CheckBox_Checked));
        }
    }

这是我的CheckBox_Checked事件处理程序,以防有用......

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        // get the selected sheets
        var selectedSheets = SheetListGrid.SelectedItems;

        if (selectedSheets.Count == 0) return;

        foreach (var item in selectedSheets)
        {
            //DataGridRow row = SheetListGrid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;

            FakeSheet sheet = item as FakeSheet;
            if (sheet.Selected == false)
                sheet.Selected = true;
        }
        SheetListGrid.Items.Refresh();
    }

我觉得好像我错过了一些让这更容易的东西,但是我无法理解它,而且我已经从我打开的标签数量几乎融化了我的RAM。我应该注意,这个项目将是一个类库,我不能包含任何第三方程序集。另外,我想尝试避免使用Windows.Interactivity,因为我之前遇到过将此类库分发给其他人的问题,并且计算机运行单独的版本导致错误。

0 个答案:

没有答案