0

I am trying to execute an event each time when i write any single word. For example when i write '123' in a cell, i want to run an event three times, on each value entered.

I used "TargetUpdated" event and write 1, event runs successfully, but when i write 2 and again 3 event does not run. Please see my code below:

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
            {
            }
       }          

The reason of achieving this behavior is to get the sum of datagrid linetotal on each value entered. Please anyone help and guide, Thanks.

Updated: Please get the video from below link in which i am trying to explain. Sample Video

Rauf Abid
  • 313
  • 2
  • 8
  • 24

2 Answers2

0

Try using the KeyDown event instead of TargetUpdated. It will call the event every time you push a key.

More key behaviours: https://stackoverflow.com/a/5871419/5147720

Community
  • 1
  • 1
Jose
  • 1,857
  • 1
  • 16
  • 34
0

As I can understand you need some mechanism to handle user keyboard inputs on a data grid cell. Here what I can suggest you; use an two attached properties. First is a boolean to enable the handling machanism, and the second is an Action tha will support the view model's action to perform the handling itself. You can attach this functionality via DataGridCell's style. Here is a described solution: 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. Attached properties code:

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 and model code:

    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. First of all try to calm down, good job, the application looks well, so is a xaml.
  2. As I can seen ALL your update logic is based on the PreviewKeyDown, there is still the old value at the moment of 'preview'. Try to base your logic on PreviewKeyUp or on KeyUp when the value is already changed. Let me know if it will help.

I hope this will help you. Regards,

Ilan
  • 2,762
  • 1
  • 13
  • 24
  • Thanks for the reply, its look horrible to me, "Kirenenko" answer looks fine, but only issue is that my entered value does not updated to my binded ObservableCollection and just give me a previous value, for example when i write 1 and then 2 in a cell, it gives me the value 1. So how can i get the latest pressed key and rebind to ObservableCollection , thanks. – Rauf Abid Nov 04 '15 at 17:49
  • @RaufAbid first of all this is a working MVVM principles based solution. about the question; it is not clear. what observable collection you meen? where is this collection? can you put the xaml? just for the case; the observable collection binded to datagrid represent its data context, each member of that collection is the data context of the row, each collection member object property is the datacontext of the cell, make each property raise the event on ths update (implement the INotifyPropertyChanged an raise its event on each cell data context object's property update). – Ilan Nov 05 '15 at 06:32
  • @llan, I have updated my question and uploaded a video, please download and see all steps of my code and help me accordingly, Appreciate your help :). – Rauf Abid Nov 05 '15 at 10:28
  • @RaufAbid edited, check this out. at the end of the answer. – Ilan Nov 05 '15 at 10:58
  • @llan, you rocked, no words to thank you. that is working perfectly, thank you v v much, GOD BLESS YOU :). – Rauf Abid Nov 05 '15 at 12:12
  • @RaufAbid you're welcome and thank you to, I was glad to help. – Ilan Nov 05 '15 at 13:11