代码之家  ›  专栏  ›  技术社区  ›  Roxy'Pro

如何在DataGrid中检测行是否被单击并将其列从true更改为false,反之亦然?

  •  0
  • Roxy'Pro  · 技术社区  · 6 年前

    我正在处理一个小的WPF应用程序,当我单击一行时,我将复选框列设为选中/未选中。我的行是这样的:

    enter image description here

    这是我的密码:

    private void dtgTest_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (dtgTest.SelectedItem != null)
        {
            CheckBox checkbocColumn = (dtgTest.Columns[3].GetCellContent(dtgTest.SelectedItem) as CheckBox);
            checkbocColumn.IsChecked = !checkbocColumn.IsChecked;
    
    
            var selectedItem = (BillItemInSerie)dtgTest.SelectedItem;
            var obj = serialNumbersIn.FirstOrDefault(sn => selectedItem.DocumentItemInSeriesId == sn.DocumentItemInSeriesId);
            obj.IsChecked= (bool)checkbocColumn.IsChecked;
    
        }
    }
    

    public Test_Window()
       : this()
    {
        databaseValues = Controller.Instance.GetById(Id);
        dtgTest.ItemsSource = null;
        dtgTest.ItemsSource = databaseValues;
    }
    

    因此,当表单生成时,我会从数据库中意外地获取所有项

    这是我的XAML:

    <DataGrid Name="dtgTest"  IsReadOnly="True"  VirtualizingStackPanel.VirtualizationMode="Standard"  EnableColumnVirtualization = "True" EnableRowVirtualization ="True"  MaxWidth="4000" MaxHeight="2000" Background="White" Margin="5,5,5,0" AutoGenerateColumns="False" RowHeaderWidth="0"  HorizontalGridLinesBrush="#0091EA" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" RowHeight="30" Grid.ColumnSpan="2" Grid.Row="2" SelectionChanged="dtgTest_SelectionChanged">
        <DataGrid.CellStyle>
            <StaticResource ResourceKey="DataGridCentering"/>
        </DataGrid.CellStyle>
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridColumnHeader}">
                <Setter Property="Background" Value="#0091EA"/>
                <Setter Property="Opacity" Value="1"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="HorizontalContentAlignment" Value="Center" />
                <Setter Property="FontSize" Value="{x:Static local:Globals.dataGridfontSizeHeader}"/>
                <Setter Property="FontFamily" Value="Arial"/>
                <Setter Property="Height" Value="40"/>
            </Style>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
               Color="LightBlue"/>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn         Binding="{Binding Value1}"          Header=""   Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*"  />
            <DataGridTextColumn         Binding="{Binding Value2}"          Header=""   Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*"   />
            <DataGridTextColumn         x:Name="colFormatedDate"            Binding="{Binding ExpireDate, StringFormat ={}{0:MM/yyyy}}"     Header=""   Foreground="Black"      FontSize="15" FontFamily="Verdana" Width="20*" />
            <DataGridCheckBoxColumn     x:Name="colSelektiraj"              Binding="{Binding IsChecked}"       Header=""  Width="10*" />
        </DataGrid.Columns>
    </DataGrid>
    

    如上图所示 ),如果我立即改变主意并再次单击选中的行以更改复选框列的状态,我将无法这样做,因为 dtgTest_SelectionChanged 不会触发,因为我没有更改选择。。

    所以我想检测一行是否被点击可能对我有帮助?所以我可能会执行类似的代码 DTG测试选择已更改 事件?

    任何形式的帮助都会很棒!

    干杯

    Rekshino帮助后编辑:

    <DataGrid Name="dtgTest" IsReadOnly="True"  VirtualizingStackPanel.VirtualizationMode="Standard"  EnableColumnVirtualization = "True" EnableRowVirtualization ="True"  MaxWidth="4000" MaxHeight="2000" Background="White" Margin="5,5,5,0" AutoGenerateColumns="False" RowHeaderWidth="0"  HorizontalGridLinesBrush="#0091EA" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" RowHeight="30" Grid.ColumnSpan="2" Grid.Row="2" SelectionChanged="dtgTest_SelectionChanged" PreviewMouseDown="dtgTest_PreviewMouseDown">
        <DataGrid.CellStyle>
            <StaticResource ResourceKey="DataGridCentering"/>
        </DataGrid.CellStyle>
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridColumnHeader}">
                <Setter Property="Background" Value="#0091EA"/>
                <Setter Property="Opacity" Value="1"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="HorizontalContentAlignment" Value="Center" />
                <Setter Property="FontSize" Value="{x:Static local:Globals.dataGridfontSizeHeader}"/>
                <Setter Property="FontFamily" Value="Arial"/>
                <Setter Property="Height" Value="40"/>
            </Style>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue"/>
            <Style TargetType="DataGridCell">
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="dtgTest_PreviewMouseDown"/>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn         Binding="{Binding Value1}"          Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*"  />
            <DataGridTextColumn         Binding="{Binding Value2}"          Foreground="Black" FontSize="15" FontFamily="Verdana" Width="35*"   />
            <DataGridTextColumn         x:Name="colFormatedDate"            Binding="{Binding ExpireDate, StringFormat ={}{0:MM/yyyy}}"   Foreground="Black"      FontSize="15" FontFamily="Verdana" Width="20*" />
            <DataGridCheckBoxColumn     x:Name="colSelektiraj"              Binding="{Binding IsChecked, NotifyOnTargetUpdated=True}"     Header=""  Width="10*" />
        </DataGrid.Columns>
    </DataGrid>
    

    private void dtgTest_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
    
        var cell = sender as DataGridCell;
    
        if (cell == null)
        {
            return;
        }
    
        DataGridRow parGridRow = null;
        var visParent = VisualTreeHelper.GetParent(cell);
        while (parGridRow == null && visParent != null)
        {
            parGridRow = visParent as DataGridRow;
            visParent = VisualTreeHelper.GetParent(visParent);
        }
        if (parGridRow == null) { return; }
    
        var selectedItem = (parGridRow.DataContext as BillItemInSerie);
        var obj = serialNumbersIn.FirstOrDefault(sn => selectedItem.DocumentItemInSeriesId == sn.DocumentItemInSeriesId);
        obj.IsChecked = (bool)!obj.IsChecked;
    }
    
    3 回复  |  直到 6 年前
        1
  •  2
  •   Rekshino    6 年前

    您可以为单元格设置鼠标事件处理程序,获取行并使用它生成所需的内容。我已删除的事件处理程序 SelectionChanged

    <DataGrid Name="dtgTest"  IsReadOnly="True"  VirtualizingStackPanel.VirtualizationMode="Standard"  EnableColumnVirtualization = "True" EnableRowVirtualization ="True"  MaxWidth="4000" MaxHeight="2000" Background="White" Margin="5,5,5,0" AutoGenerateColumns="False" RowHeaderWidth="0"  HorizontalGridLinesBrush="#0091EA" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False" RowHeight="30" Grid.ColumnSpan="2" Grid.Row="2">
        <DataGrid.Resources>
            <Style TargetType="DataGridCell">
            <!-- If you have to apply another style, then use BasedOn-->
            <!--<Style TargetType="DataGridCell" BasedOn="{StaticResource DataGridCentering}">-->
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="PreviewMouseDown"/>
            </Style>
        </DataGrid.Resources>
        ...
    </DataGrid>
    
    private void PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        var cell = sender as DataGridCell; if (cell == null) { return; }
        DataGridRow parGridRow = null;
        var visParent = VisualTreeHelper.GetParent(cell);
        while (parGridRow == null && visParent != null)
        {
            parGridRow = visParent as DataGridRow;
            visParent = VisualTreeHelper.GetParent(visParent);
        }
        if (parGridRow == null) { return; }
        var selectedItem = (parGridRow.DataContext as BillItemInSerie);
        var obj = serialNumbersIn.FirstOrDefault(sn => selectedItem.DocumentItemInSeriesId == sn.DocumentItemInSeriesId);
        obj.IsChecked= (bool)!obj.IsChecked;
    
        //e.Handled = true;
    }
    
        2
  •  0
  •   Prateek Shrivastava    6 年前

    如果有表示每行数据的ViewModel(MVVM)。您应该/可以在那里有一个表示复选框状态的bool属性(而不是从代码隐藏处执行此操作)。

    接下来,您可以将DataGrid的SelectedItem绑定到一个对象(相关类型),并测试即使您多次单击同一项,该对象是否被激发。如果是这样(至少在DevExpress gridControls中是这样)-您应该在SelectedItem的Setter中翻转bool属性。

        3
  •  0
  •   dstreissi    6 年前

    嗨,您可以在checkboxcolumn的绑定上设置一个标志。 NotifyOnTargetUpdated 带着火和 TargetUpdated 目标(复选框)更改时的事件。

    NotifyOnTargetUpdated=True 在绑定时激活它们。 你的 DataGridCheckBoxColumn 看起来是这样的:

    <DataGridCheckBoxColumn x:Name="colSelektiraj" Binding="{Binding IsChecked, NotifyOnTargetUpdated=True}" Header="" Width="10*" />
    

    TargetUpdated="DataGrid_TargetUpdated" 要获得通知的事件。您的数据网格如下所示:

    <DataGrid Name="dtgTest" IsReadOnly="True" TargetUpdated="DataGrid_TargetUpdated" ...>
    

    SelectionChanged 就像你已经做的那样。