如何对 WPF Datagrid 单元格中输入的每个值执行事件

How to Execute Event on Each Value Entered in WPF Datagrid Cell

每次我写任何一个字时,我都试图执行一个事件。例如,当我在一个单元格中写“123”时,我想 运行 一个事件三次,每次输入一个值。

我使用 "TargetUpdated" 事件并写入 1,事件 运行 成功,但是当我再次写入 2 和 3 时,事件没有 运行。请在下面查看我的代码:

private void maingrid_TargetUpdated(object sender, DataTransferEventArgs e)
        {

            try
            {
                DataGrid Currcell = sender as DataGrid;
                int index = Currcell.CurrentColumn.DisplayIndex;
                vm.SetLineTotals(vm.Tax, vm.DiscountPer);
            }
            catch
            {
            }
       }          

实现此行为的原因是获取每个输入值的 datagrid linetotal 总和。请任何人帮助和指导,谢谢。

更新: 请从下方 link 获取我正在尝试解释的视频。 Sample Video

尝试使用 KeyDown 事件而不是 TargetUpdated。每次你按下一个键它都会调用这个事件。

更多关键行为:

据我所知,您需要某种机制来处理数据网格单元格上的用户键盘输入。在这里我可以建议你;使用两个附加属性。第一个是启用处理机制的布尔值,第二个是一个 Action,它将支持视图模型的操作来执行处理本身。您可以通过 DataGridCell 的样式附加此功能。这是一个描述的解决方案: 1. Xaml:

<Window x:Class="soHelpProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:soHelpProject="clr-namespace:SoHelpProject"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <soHelpProject:MainViewModel/>
</Window.DataContext>
<Grid>
    <DataGrid ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <Style TargetType="DataGridCell">
                <Setter Property="soHelpProject:Attached.IsReactsOnKeyDown" Value="True"></Setter>
                <Setter Property="soHelpProject:Attached.OnKeyDownAction" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.OnKeyDownAction}"></Setter>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Width="120" Binding="{Binding Name}"></DataGridTextColumn>
            <DataGridTextColumn Width="120" Binding="{Binding Surname}"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid></Window>

2。附加属性代码:

public class Attached
{
    public static readonly DependencyProperty OnKeyDownActionProperty = DependencyProperty.RegisterAttached(
        "OnKeyDownAction", typeof (Action<object>), typeof (Attached), new PropertyMetadata(default(Action<object>)));

    public static void SetOnKeyDownAction(DependencyObject element, Action<object> value)
    {
        element.SetValue(OnKeyDownActionProperty, value);
    }

    public static Action<object> GetOnKeyDownAction(DependencyObject element)
    {
        return (Action<object>) element.GetValue(OnKeyDownActionProperty);
    }

    public static readonly DependencyProperty IsReactsOnKeyDownProperty = DependencyProperty.RegisterAttached(
        "IsReactsOnKeyDown", typeof (bool), typeof (Attached), new PropertyMetadata(default(bool), IsReactsOnKeyDownPropertyChangedCallback));

    private static void IsReactsOnKeyDownPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        var val = (bool)args.NewValue;
        var cell = sender as DataGridCell;
        if(cell == null) 
            return;
        if (val == false)
        {
            cell.KeyDown -= CellOnKeyDown;
        }
        else
        {
            cell.KeyDown += CellOnKeyDown;
        }

    }

    private static void CellOnKeyDown(object sender, KeyEventArgs keyEventArgs)
    {
        var cell = sender as DataGridCell;
        if (cell == null)
            return;
        var action = cell.GetValue(OnKeyDownActionProperty) as Action<object>;
        if (action == null) return;
        action(keyEventArgs);
    }

    public static void SetIsReactsOnKeyDown(DependencyObject element, bool value)
    {
        element.SetValue(IsReactsOnKeyDownProperty, value);
    }

    public static bool GetIsReactsOnKeyDown(DependencyObject element)
    {
        return (bool) element.GetValue(IsReactsOnKeyDownProperty);
    }
}

3。 ViewModel 和模型代码:

    public class MainViewModel:BaseObservableObject
{
    private Action<object> _onKeyDownAction;
    private ObservableCollection<Person> _collection;

    public MainViewModel()
    {
        Collection = new ObservableCollection<Person>
        {
            new Person
            {
                Name = "John",
                Surname = "A"
            },
            new Person
            {
                Name = "John",
                Surname = "B"
            },
            new Person
            {
                Name = "John",
                Surname = "C"
            },
        };
        OnKeyDownAction = new Action<object>(KeyWasPressed);
    }

    private void KeyWasPressed(object o)
    {
        var args = o as KeyEventArgs;
        if(args == null)
            return;
        Debug.WriteLine(args.Key.ToString());
    }

    public Action<object> OnKeyDownAction
    {
        get { return _onKeyDownAction; }
        set
        {
            _onKeyDownAction = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<Person> Collection  
    {
        get { return _collection; }
        set
        {
            _collection = value;
            OnPropertyChanged();
        }
    }
}

public class Person:BaseObservableObject
{
    private string _name;
    private string _surname;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public string Surname
    {
        get { return _surname; }
        set
        {
            _surname = value;
            OnPropertyChanged();
        }
    }
}
  1. 首先试着冷静下来,干得好,申请看起来不错,所以是xaml。
  2. 据我所见ALL你的更新逻辑是基于PreviewKeyDown的,在'preview'的那一刻仍然有旧值。当值已更改时,请尝试将您的逻辑基于 PreviewKeyUp 或基于 KeyUp。让我知道它是否有帮助。

希望对您有所帮助。 此致,