1

I wrote update function, I want to when I double-click a data in the listview, data will be shown in a textbox. I search and find many solutions, I have a example:

`<ListView ItemsSource="{Binding listHocVien}"
           SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}">
      <ListView.InputBindings>
            <MouseBinding MouseAction="LeftDoubleClick" />
      </ListView.InputBindings>
      <ListView.View>
         <GridView>
            <GridViewColumn Header="Name"
                            DisplayMemberBinding="{Binding Name}">
            </GridViewColumn>
         </GridView>
      </ListView.View>
 </ListView>`

But I when I run the app and click data, I just need one click, not double-click. I have to find the solution on the internet and didn't see anyone said to write an event for LeftDoubleClick. So, did we need to write the event to LeftDoubleClick? If yes, can anyone show me examples. Thank for all your help.

1 Answers1

1

You could use behaviours: How to add System.Windows.Interactivity to project?.

This way you could create a double click command and bind it to your view model class. In the execute of your command you could set the property of the textbox to the desired text

After you've added in your project you should reference the namespace in the xaml code. If you reference it as i then your code to add the behaviour to the list view should be as follows:

In your xaml:

<TextBox Text ="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>

<ListView>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding YourCommand}"
                                   CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListView>

In your View Model:

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

public class SampleViewModel : INotifyPropertyChanged {
    private string _Text;
    public event PropertyChangedEventHandler PropertyChanged;

    public string Text {
        get { return _Text; }
        set {
            if (_Text != value) {
                _Text = value;
                RaisePropertyChanged();
            }
        }
    }

    public ICommand YourCommand { get; set; }

    public SampleViewModel() {
        YourCommand = new RelayCommand<TType>(YourCommandExecute); // that TType is the type of your elements in the listview
    }


    // Here I will assume that your TType has a property named Description
    private void YourCommandExecute(TType selectedElement) {
        Text = selectedItem.Description;
    }

    public void RaisePropertyChanged([CallerMemberName] propertyName = null) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Relay Command Implementation

// Simple Implementation of Generic Relay Command:
public class RelayCommand<T> : ICommand
{
    private Action<T> execute;
    private Func<T,bool> canExecute;

    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action<T> execute,Func<T,bool> canExecute=null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return canExecute == null || canExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
        execute((T)parameter);
    }
}
carlos chourio
  • 853
  • 7
  • 16
  • hi carlos shourio, what is into `YourCommand`? I need to write event in `YourCommand`, right? – Toan Nguyen Phuoc Jun 20 '19 at 13:47
  • @ToanNguyenPhuoc: `YourCommand` is a property that returns an `ICommand`. You should either implement `ICommand` yourself or use an implemenetation from some MVVM library. – mm8 Jun 20 '19 at 13:51
  • I guess you're not familiar with mvvm *Commands*, right? You should create a property in the view model class of type ICommand named YourCommand or whatever name you want, then you have to create that property of type RelayCommand or DelegateCommand... and Initialize them with the method you want to perform after the double click. For more information about commands check this out: https://www.wpf-tutorial.com/commands/using-commands/ – carlos chourio Jun 20 '19 at 13:52
  • when I double-click, my app will run what I write in `YourCommand`, right? – Toan Nguyen Phuoc Jun 20 '19 at 14:03
  • Yes, this is first time I use MVVM :( – Toan Nguyen Phuoc Jun 20 '19 at 14:04
  • Yes, you have to add that reference. No, your app is going to execute what you'll write on YourCommandExecute method. I'd recommend you to watch a few courses about mvvm or read some articles. It may be quite difficult when you're starting with it. – carlos chourio Jun 20 '19 at 14:05
  • I added an EDIT for a very simple implementation of commands from scratch – carlos chourio Jun 20 '19 at 14:25
  • In default Listview, I click one times and data will be shown in a textbox. Suppose, `YourCommand` is null, I add : `xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"`. Can I double-click and data will show in a textbox? – Toan Nguyen Phuoc Jun 20 '19 at 15:03
  • YourCommand is not supposed to be null, since you're initilizing it in the view model. In you Bind the property Text of your textbox to a property in the view model you should be able to inmediately fill the textbox when you double click. I will edit the answer to show you how. – carlos chourio Jun 20 '19 at 15:12
  • 1
    Thank you, I'm so grateful for your help. I solved my problems. Your code helped me very much to know command. Thank you very much, again. – Toan Nguyen Phuoc Jun 20 '19 at 16:14
  • hi carlos chourio, are you there? – Toan Nguyen Phuoc Jul 01 '19 at 16:25