ツリービューのマウスダブルクリックイベントを処理するための依存関係プロパティを作成しました。ツリービューアイテムをダブルクリックすると、ビューモデルで必要なメソッドが呼び出されるという点で部分的に機能しています。次に、クリックしたアイテム(XmlElement)をこのメソッドにパススルーします。別のDependencyプロパティを追加しました。パラメータの場合ですが、ツリービューアイテムをダブルクリックするたびに、メソッドのXmlElementパラメータはですnull
。
次のような外部ライブラリがいくつかあります。
1)Expression.Sample.Interactivityおよび
しかし、私は自分で何かを実装するように頼まれました、そして誰かが私がどこで間違っているのかアドバイスしてくれるなら本当にありがたいです。私は以下に必要な情報源を含めました:
依存関係プロパティを処理するクラス:
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
}
}