2012-07-26 154 views
1

我创建了一个Dependency属性来处理树视图的鼠标双击事件。 这是部分工作,当你双击树视图项目在我的视图模型中调用所需的方法,现在我想要做的是通过点击项目(XmlElement)到这个方法。我添加了另一个依赖项属性,但每次我双击树视图项时,方法中的XmlElement参数是null处理WPF TreeView鼠标双击使用MVVM

有一些外部库,如:

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

回答

5

将断点在此行

command.Execute(sender as XmlElement); 

你会发现发件人是XmlElement类型的不(这是树视图),因此你总是得到null。 您必须检索您绑定的CommandParameter(它是XmlElement),并将其指定给Execute调用。