使用MVVM处理WPF TreeView鼠标双击

时间:2012-07-26 07:18:42

标签: c# wpf mvvm .net-4.0

我创建了一个Dependency Property来处理树视图的鼠标双击事件。 部分工作在于,当您双击树视图项时,在我的视图模型中调用所需的方法,现在我想要做的是将单击的项(XmlElement)传递给此方法。我添加了另一个Dependency属性对于参数,但每次双击树视图项时,方法中的XmlElement参数为null

有许多外部库,例如:

1)Expression.Sample.Interactivity

2)Attached Command Behavior

但是我被要求自己实施一些东西,如果有人可以建议我哪里出错,我会非常感激。我已经在下面提供了必要的资料来源:

处理依赖项属性的类:

  public static class CommandBehavior
  {

  public static readonly DependencyProperty DoubleClickCommand =
  EventBehaviourFactory.CreateCommandExecutionEventBehaviour(
  TreeView.MouseDoubleClickEvent,
  "DoubleClickCommand",
 typeof(CommandBehavior));

public static void SetDoubleClickCommand(DependencyObject o, ICommand value)
{
    o.SetValue(DoubleClickCommand, value);
}

public static ICommand GetDoubleClickCommand(DependencyObject o)
{
    return o.GetValue(DoubleClickCommand) as ICommand;
}

public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter", 
typeof(object),
typeof(CommandBehavior),
new FrameworkPropertyMetadata((object)null,
    new PropertyChangedCallback(OnCommandParameterChanged)));

public static object GetCommandParameter(DependencyObject d)
{
    return (object)d.GetValue(CommandParameterProperty);
}

public static void SetCommandParameter(DependencyObject d, object value)
{
    d.SetValue(CommandParameterProperty, value);
}

private static void OnCommandParameterChanged(DependencyObject d,  DependencyPropertyChangedEventArgs e)
{
}

}

 public static class EventBehaviourFactory
 {
 public static DependencyProperty CreateCommandExecutionEventBehaviour(RoutedEvent routedEvent, string propertyName, Type ownerType)
 {
    DependencyProperty property = DependencyProperty.RegisterAttached(propertyName, typeof(ICommand),
        ownerType, new PropertyMetadata(null,
            new ExecuteCommandOnRoutedEventBehaviour(routedEvent).PropertyChangedHandler));
    return property;
}

}

public class ExecuteCommandOnRoutedEventBehaviour : ExecuteCommandBehaviour
{
   private readonly RoutedEvent _routedEvent;
   public ExecuteCommandOnRoutedEventBehaviour(RoutedEvent routedEvent)
   {
      _routedEvent = routedEvent;
   }

 protected override void AdjustEventHandlers(DependencyObject sender, object oldValue,   object newValue)
 {
    UIElement element = sender as UIElement;
    if (element == null)
        return;

    if (oldValue != null)
    {
        element.RemoveHandler(_routedEvent, new RoutedEventHandler(EventHandler));
    }
    if (newValue != null)
    {
        element.AddHandler(_routedEvent, new RoutedEventHandler(EventHandler));
    }
}

protected void EventHandler(object sender, RoutedEventArgs e)
{
    HandleEvent(sender, e);
}

}

public abstract class ExecuteCommandBehaviour
{
protected DependencyProperty _property;
protected abstract void AdjustEventHandlers(DependencyObject sender, object oldValue, object newValue);
protected void HandleEvent(object sender, EventArgs e)
{
    DependencyObject dp = sender as DependencyObject;
    if (dp == null)
        return;

    DelegateCommand<XmlElement> command = dp.GetValue(_property) as DelegateCommand<XmlElement>;
    if (command == null)
    {
        return;
    }
    command.Execute(sender as XmlElement);
}

public void PropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    if (_property == null)
        _property = e.Property;

    object oldValue = e.OldValue;
    object newValue = e.NewValue;
    AdjustEventHandlers(sender, oldValue, newValue);
}

}

相关XAML:

<TreeView Name="treeView1"
          local:CommandBehavior.DoubleClickCommand="{Binding ClickedItem}"
          local:CommandBehavior.CommandParameter="{Binding ElementName=treeView1, Path=SelectedItem}">

查看型号:

 public partial class FieldTreeViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        private DelegateCommand<XmlElement> _clickedItem;
        public DelegateCommand<XmlElement> ClickedItem 
        {
            get { return _clickedItem; }
            set 
            { 
                _clickedItem = value;
                OnPropertyChanged("ClickedItem");
            }
        }

        public FieldTreeViewModel()
        {
            ClickedItem = new DelegateCommand<XmlElement>(InsertContentControl);
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private void InsertContentControl(XmlElement selectedElement)
        {
            //The method always get's executed when tree view item is double clicked but
            //the selectedElement parameter is always null
        }
    }

1 个答案:

答案 0 :(得分:5)

在这一行设置一个断点

command.Execute(sender as XmlElement);

您会注意到发件人不属于XmlElement类型(它是树视图),因此您始终获得null。 您必须检索绑定到的CommandParameterXmlElement)并将其指定给Execute来电。