使用MVVM在WPF DataGrid CellEditEnding事件中取消后,将光标保留在单元格中

时间:2018-10-25 04:26:46

标签: c# wpf

我正在编辑的数据网格中有一个单元格。单元格编辑结束后,我正在网格中使用CellEditEnding事件捕获该事件并进行一些验证。如果验证失败,则需要将光标留在该单元格中,而不要继续到下一个单元格。如您所见,我将cancel设置为true,但是所有要做的就是将单元格保持在编辑模式,并且仍然使光标转到下一个单元格。我需要一种将光标保持在单元格中的方法,直到一切正常为止。

xaml:

<DataGrid Style="{StaticResource ApplicationTabDataGridStyle}"
          ItemsSource="{Binding CurrentContacts, Mode=TwoWay}"
          SelectedValue="{Binding AddressGridItemSelected}"
          x:Name="ChangeInfoAddressGrid">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="CellEditEnding">
            <command:EventToCommand PassEventArgsToCommand="True"
                                    Command="{Binding ValidateAddressRowCommand}"/>
    </i:EventTrigger>
    </i:Interaction.Triggers>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Address 1" MinWidth="60"
                            Binding="{Binding Addr1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                            IsReadOnly="{Binding Data.AddressGridItemSelected.CanEdit, 
                                                 Converter={StaticResource boolToOppositeBoolConverter}, 
                                                 Source={StaticResource IsReadyOnlyProxy}}">
            <DataGridTextColumn.EditingElementStyle>
                <Style TargetType="TextBox">
                    <Setter Property="MaxLength" Value="26" />
                </Style>
            </DataGridTextColumn.EditingElementStyle>
        </DataGridTextColumn>

    ...

    </DataGrid.Columns>
</DataGrid>

c#

public RelayCommand<object> ValidateAddressRowCommand => new RelayCommand<object>(ValidateAddressRow);
private void ValidateAddressRow(object eventArgs)
{
    var cellEventArgs = eventArgs as DataGridCellEditEndingEventArgs;
    // DO SOME VALIDATION

    ...

    cellEventArgs.Cancel = true;     
    cellEventArgs.EditingElement.Focus();
}

2 个答案:

答案 0 :(得分:0)

我已使用DataGrid_CellEditEnding事件处理程序完成此操作,并使用调度程序达到了目标(我有一个数据网格):

private void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    e.Cancel = true;
    (sender as DataGrid).Dispatcher.BeginInvoke((Action)(()=>
        {
            (sender as DataGrid).SelectedIndex = e.Row.GetIndex();
            e.EditingElement.Focus();
        }
    ));
}

您可以根据需要进行调整。我很困惑,您在ViewModel中使用View类(DataGridCellEditEndingEventArgs)。

答案 1 :(得分:0)

我不确定这是否是最好的解决方案,但是您可以尝试PreviewKeyDown事件,该事件在那里捕获多个键并有条件地将KeyEventArgs e.Cancel设置为true。然后,DataGrid将不执行任何操作。鼠标也一样。

最后,这可能有助于保持相同的单元格编辑模式

private void DataGrid_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.OldFocus is TextBox textBox)
    { 
        // some validation may be applied here to textBox.Text
        e.Handled = true;
    }
}