Задать вопрос
@DarkByte2015

Двойной клик по итему ListBox-а?

Подскажите пожалуйста как мне повесить команду (ICommand) на двойной клик по итему ListBox-а?
  • Вопрос задан
  • 2210 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
lexxpavlov
@lexxpavlov
Программист, преподаватель
Нужно просто поставить привязку с командой у вашей вьюмодели. Вы ведь используете MVVM?

Гораздо удобнее использовать не создавать вручную ICommand, а сделать класс, реализующий этот интерфейс. Обычно его называют DelegateCommand (классы указаны ниже).

И дальше во вьюмодели создаёте свойство для команды и привязывайте то место, где нужна команда, к созданной команде во вьюмодели.

#region Свойства

public ObservableCollection<MyClass> Collection { get; set; } = new ObservableCollection<MyClass>
{
    new MyClass { Name = "Иванов Иван" },
    new MyClass { Name = "Петров Пётр" },
    new MyClass { Name = "Сидоров Сидор" },
};
public MyClass SelectedCollection { get; set; };

#endregion

#region Команды

private ActionCommand _myCommand;
public ActionCommand MyCommand => _myCommand ?? (_myCommand = new ActionCommand(MyMethod));

private DelegateCommand<MyClass> _myDelegateCommand;
public DelegateCommand<MyClass> MyDelegateCommand => _myDelegateCommand ?? (_myDelegateCommand = new DelegateCommand<MyClass>(MyMethod2, item => item != null);

private void MyMethod()
{
    // обработка команды
}

private void MyMethod2(MyClass item)
{
    // обработка команды
}

#endregion


<ListBox ItemsSource="{Binding Collection}" SelectedItem="{Binding SelectedItem}"/>
<Button Command="{Binding MyCommand}" Content="Команда 1"/>
<Button Command="{Binding MyDelegateCommand}" CommandParameter="{Binding SelectedItem}" Content="Команда 2"/>


Если нужна команда не на событие Сlick, а на любое другое событие (как вы говорите, на DoubleClick), то нужно сделать добавить референс на System.Windows.Interactivity и указать триггер на событие:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

<ListBox ItemsSource="{Binding Collection}" SelectedItem="{Binding SelectedItemc}" DisplayMemberPath="Name">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding MyDelegateCommand}" CommandParameter="{Binding SelectedItem}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>


Класс DelegateCommand - команда с параметром, и класс ActionCommand - команда без параметра. Нешаблонный класс DelegateCommand используется реже (я вообще не припомню, чтобы его использовал).
public class DelegateCommand<T> : ICommand
{
    #region Private fields

    private readonly Action<T> _execute;
    private readonly Func<T, bool> _canExecute;

    #endregion

    #region Constructors

    public DelegateCommand(Action<T> execute, Func<T, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion

    #region DelegateCommand

    public void Execute(T parameter)
    {
        var handler = _execute;
        if (handler != null)
        {
            handler(parameter);
        }
    }

    public bool CanExecute(T parameter)
    {
        var handler = _canExecute;
        return handler == null || handler(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    #endregion

    #region ICommand

    void ICommand.Execute(object parameter)
    {
        Execute((T)parameter);
    }

    bool ICommand.CanExecute(object parameter)
    {
        return CanExecute((T)parameter);
    }

    #endregion
}

public class DelegateCommand : DelegateCommand<object>
{
    public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
        : base(execute, canExecute)
    {
    }
}

public class ActionCommand : DelegateCommand<object>, ICommand
{
    #region Private fields

    private readonly Action _action;
    private readonly Func<bool> _canExecute;

    #endregion

    #region Constructors

    public ActionCommand(Action action, Func<bool> canExecute = null)
        : base(null, null)
    {
        _action = action;
        _canExecute = canExecute;
    }

    #endregion

    #region ActionCommand

    public void Execute()
    {
        var handler = _action;
        if (handler != null)
        {
            handler();
        }
    }

    public bool CanExecute()
    {
        var handler = _canExecute;
        return handler == null || handler();
    }

    #endregion

    #region ICommand

    void ICommand.Execute(object parameter)
    {
        Execute();
    }

    bool ICommand.CanExecute(object parameter)
    {
        return CanExecute();
    }

    #endregion
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы