Значение ячейки catch DataGrid изменило событие одним щелчком на UpdateSourceTrigger = SourceUpdated

Я пытаюсь поймать событие с помощью DataGrid. То, что я хочу достичь, заключается в том, что когда пользователь нажимает ONCE на флажке ячейки datagrid, срабатывает событие, и я могу получить текущее значение ячейки. Однако CellChangedEvent срабатывает только тогда, когда выбор изменяется, и CellEditingEvent либо срабатывает, когда ячейка теряет фокус, либо никогда не срабатывает. Он никогда не срабатывает, если я попытаюсь сделать флажок изменяемым одним щелчком мыши, выполнив следующие действия:

<DataGrid Grid.ColumnSpan="2" Grid.Row="1" Grid.Column="0" AutoGenerateColumns="True" ItemsSource="{Binding MasterDataTable, Mode=TwoWay}" CanUserAddRows="False" Margin="10 5" CurrentCellChanged="DataGrid_CurrentCellChanged">
            <DataGrid.Resources>
                <Style TargetType="DataGridCell">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="IsEditing" Value="True" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
        </DataGrid>

Как я могу вызвать метод, как только пользователь нажмет флажок внутри ячейки? Спасибо заранее.

Ответ 1

1) В вашем регистре DataGrid для события TargetUpdated.

2) Укажите столбец и в идеале установите AutoGenerateColumns = False.

3) В вашем флага привязки свойство NotifyOnTargetUpdated (ваша цель - ваш флажок).

4) В вашем Binding UpdateSourceTrigger = PropertyChanged и Mode = TwoWay (а не поведение DataGrid по умолчанию).

XAML:

 <DataGrid TargetUpdated="DataGrid_TargetUpdated" 
           AutoGenerateColumns="False" 
           ItemsSource="{Binding SomeValues, Mode=OneWay}"  CanUserAddRows="False"  >
    <DataGrid.Columns>
        <DataGridCheckBoxColumn Binding="{Binding Path=.,  NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Width="*"/>                        
    </DataGrid.Columns>
</DataGrid>

в CS: (где вы могли бы не обрабатывать это событие.)

   private void DataGrid_TargetUpdated(object sender, DataTransferEventArgs e)
   {
         // Do what ever...
   }  

Ответ 2

Вот как я это решил. Это не лучшее решение, но оно работает для меня. Как указано в @eranotzap, я устанавливаю set AutoGenerateColumns = False и UpdateSourceTrigger = PropertyChanged. Затем я сделал следующее:

<DataGrid Grid.ColumnSpan="2" Grid.Row="1" Grid.Column="0" 
          AutoGenerateColumns="False" 
          ItemsSource="{Binding MasterDataTable, Mode=TwoWay}" 
          CanUserAddRows="False" 
          Margin="10 5">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=Fornitore}" Header="Fornitore" Width="Auto" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=Stat}" Header="Stat" Width="Auto" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=Intestazione}" Header="Intestazione" Width="*" IsReadOnly="True" >
        <DataGridTextColumn.ElementStyle>
            <Style TargetType="TextBlock">
                <Setter Property="TextWrapping" Value="Wrap" />
            </Style>
        </DataGridTextColumn.ElementStyle>
        <DataGridTextColumn.EditingElementStyle>
            <Style TargetType="TextBox">
                <Setter Property="TextWrapping" Value="Wrap" />
                <Setter Property="AcceptsReturn" Value="true" />
            </Style>
        </DataGridTextColumn.EditingElementStyle>
        </DataGridTextColumn>
        <DataGridTextColumn Binding="{Binding Path=PrzVend}" Header="PrzVend" Width="Auto" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=DatEXPO}" Header="DatEXPO" Width="Auto" IsReadOnly="True" />
        <DataGridCheckBoxColumn Binding="{Binding Path=Sel, NotifyOnSourceUpdated=False, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Sel" Width="Auto">
            <DataGridCheckBoxColumn.CellStyle>
                <Style TargetType="DataGridCell">
                    <EventSetter Event="CheckBox.Checked" Handler="CellChanged"/>
                    <EventSetter Event="CheckBox.Unchecked" Handler="CellChanged"/>
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver" Value="True" />
                                <Condition Property="IsReadOnly" Value="False" />
                            </MultiTrigger.Conditions>
                            <Setter Property="IsEditing" Value="True" />
                        </MultiTrigger>
                    </Style.Triggers>
                </Style> 
            </DataGridCheckBoxColumn.CellStyle>
        </DataGridCheckBoxColumn>
        <DataGridTextColumn Binding="{Binding Path=CodComp}" Header="CodComp" Width="Auto" IsReadOnly="True" />
    </DataGrid.Columns>
</DataGrid>

В коде, стоящем за методом CellChanges, вызывается каждый раз, когда флажок установлен или снят флажок. Чтобы получить значение, я делаю следующее:

void CellChanged(object sender, RoutedEventArgs e)
{
    if (sender as DataGridCell != null && (sender as DataGridCell).Column != null && (sender as DataGridCell).Column.Header != null)
    {

        bool? isSelected = (e.OriginalSource as ToggleButton).IsChecked;

    }
}

Надеюсь, это поможет кому-то.

Ответ 3

Попробуйте этот простой способ

private void myDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.Column.SortMemberPath.Equals("EndDate"))
        {
            if (((MyObjectInRow)e.Row.Item).DataFine.Equals(EndDate.MinValue))
            {
                ((MyObjectInRow)e.Row.Item).Completed = 1;
            }
            else
            {
                ((MyObjectInRow)e.Row.Item).Completed = 0;
            }


        }
    }