zoukankan      html  css  js  c++  java
  • WPF中控件的Event转换成Command执行(转)

    细实现。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Input;
    using System.Reflection;

    namespace TestAutoGenerateColumnForGridView
    {
    public static class CommandBindingBehavior
    {
    public static DependencyProperty BindingEventNameProperty = DependencyProperty.RegisterAttached
    ("BindingEventName", typeof(string),
    typeof(CommandBindingBehavior), new PropertyMetadata(null, OnBindingEventChanged));

    public static string GetBindingEventName(DependencyObject obj)
    {
    return (string)obj.GetValue(BindingEventNameProperty);
    }

    public static void SetBindingEventName(DependencyObject obj, string value)
    {
    obj.SetValue(BindingEventNameProperty, value);
    }

    public static DependencyProperty BindingCommandProperty = DependencyProperty.RegisterAttached
    ("BindingCommand", typeof(ICommand), typeof(CommandBindingBehavior), new PropertyMetadata(null));

    public static ICommand GetBindingCommand(DependencyObject obj)
    {
    object com = obj.GetValue(BindingCommandProperty);
    if (com == null)
    return null;

    return (ICommand)com;
    }

    public static void SetBindingCommand(DependencyObject obj, ICommand value)
    {
    obj.SetValue(BindingCommandProperty, value);
    }

    private static void OnEventRaised<T>(object sender, T arg) where T: EventArgs
    {
    DependencyObject dependencyObject = sender as DependencyObject;
    if (dependencyObject != null)
    {
    ICommand command = GetBindingCommand(dependencyObject);
    if (command != null)
    {
    if (command.CanExecute(arg))
    {
    command.Execute(arg);
    }
    }
    }
    }

    private static void OnBindingEventChanged(DependencyObject sender, DependencyPropertyChangedEventArgs arg)
    {
    Type senderType = sender.GetType();
    EventInfo eventInfo = senderType.GetEvent(arg.NewValue.ToString());
    eventInfo.AddEventHandler(sender, GenerateDelegateForEventHandler(eventInfo));
    }

    private static Delegate GenerateDelegateForEventHandler(EventInfo eventInfo)
    {
    Delegate result = null;

    MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");
    ParameterInfo[] parameters = methodInfo.GetParameters();
    if (parameters.Length == 2)
    {
    Type currentType = typeof(CommandBindingBehavior);
    Type argType = parameters[1].ParameterType;
    MethodInfo eventRaisedMethod =
    currentType.GetMethod("OnEventRaised", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(argType);
    result = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventRaisedMethod);
    }

    return result;
    }

    }
    }

    使用:

    <ListView ItemsSource ="{Binding Persons}" ItemContainerStyle="{StaticResource ResourceKey=ListViewItemStyle}"
    local:CommandBindingBehavior.BindingCommand ="{Binding Path=NewFolderCommand}"
    local:CommandBindingBehavior.BindingEventName="MouseUp">
    <ListView.View>
    </ListView.View>
    </ListView>

    ModelView:

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

    Lazy<RelayCommand> mNewFolderCommand;

    public MainWindow()
    {
    InitializeComponent();
    this.DataContext = this;

    //new folder command
    mNewFolderCommand = new Lazy<RelayCommand>(() => new RelayCommand(NewFolderCommandExecuted, NewFolderCommandCanExecute));
    }
    #region NewFolderCommand

    /// <summary>
    /// Up command
    /// </summary>
    public ICommand NewFolderCommand
    {
    get { return mNewFolderCommand.Value; }
    }

    /// <summary>
    /// Executes the Up command
    /// </summary>
    private void NewFolderCommandExecuted()
    {

    }

    private bool NewFolderCommandCanExecute()
    {
    return true;
    }
    #endregion
    }

    依赖于:

    MvvMFoudation: http://wpf.codeplex.com/

    中的RelayCommand

    具体实现:

    namespace TestAutoGenerateColumnForGridView
    {
    /// <summary>
    /// A command whose sole purpose is to
    /// relay its functionality to other
    /// objects by invoking delegates. The
    /// default return value for the CanExecute
    /// method is 'true'.
    /// </summary>
    public class RelayCommand<T> : ICommand
    {
    readonly Action<T> _execute;
    readonly Predicate<T> _canExecute;

    public RelayCommand(Action<T> execute)
    : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
    if (execute == null)
    throw new ArgumentNullException("execute");

    _execute = execute;
    _canExecute = canExecute;
    }

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
    return _canExecute == null ? true : _canExecute((T)parameter);
    }

    public event EventHandler CanExecuteChanged
    {
    add
    {
    if (_canExecute != null)
    CommandManager.RequerySuggested += value;
    }
    remove
    {
    if (_canExecute != null)
    CommandManager.RequerySuggested -= value;
    }
    }

    public void Execute(object parameter)
    {
    _execute((T)parameter);
    }

    #endregion // ICommand Members
    }

    /// <summary>
    /// A command whose sole purpose is to
    /// relay its functionality to other
    /// objects by invoking delegates. The
    /// default return value for the CanExecute
    /// method is 'true'.
    /// </summary>
    public class RelayCommand : ICommand
    {
    readonly Action _execute;
    readonly Func<bool> _canExecute;
    /// <summary>
    /// Creates a new command that can always execute.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action execute)
    : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action execute, Func<bool> canExecute)
    {
    if (execute == null)
    throw new ArgumentNullException("execute");

    _execute = execute;
    _canExecute = canExecute;
    }

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
    return _canExecute == null ? true : _canExecute();
    }

    public event EventHandler CanExecuteChanged
    {
    add
    {
    if (_canExecute != null)
    CommandManager.RequerySuggested += value;
    }
    remove
    {
    if (_canExecute != null)
    CommandManager.RequerySuggested -= value;
    }
    }

    public void Execute(object parameter)
    {
    _execute();
    }

    #endregion // ICommand Members
    }
    }

  • 相关阅读:
    react性能检测与优化
    react组件在项目中的应用(基础知识)
    前端性能优化
    我们一起来详细的了解react的语法以及组件的使用方法
    和我一起使用webpack构建react项目
    babel与ES6环境的搭建
    Razor 在JS中嵌入后台变量
    HttpClient + ASP.NET Web API, WCF之外的另一个选择
    《大型网站技术架构》读书笔记[3]
    Remote Desktop Connection Manager 多个远程管理
  • 原文地址:https://www.cnblogs.com/aoldman/p/2781053.html
Copyright © 2011-2022 走看看