WPF行为和事件-附加到适当的事件

WPF行为和事件-附加到适当的事件,wpf,events,mvvm,triggers,Wpf,Events,Mvvm,Triggers,这里有一个处理拖放的行为,我通过视图附加鼠标事件。项目的视图模型继承自IDraggable。我使用Caliburn.Micro作为MVVM框架 <ItemsControl x:Name="Items"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas /> </ItemsPanelTemplate> &l

这里有一个处理拖放的行为,我通过视图附加鼠标事件。项目的视图模型继承自
IDraggable
。我使用Caliburn.Micro作为MVVM框架

<ItemsControl x:Name="Items">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
            <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
            <Setter Property="Width" Value="{Binding Path=Width}" />
            <Setter Property="Height" Value="{Binding Path=Height}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border>
                <!-- item contents -->

                <i:Interaction.Behaviors>
                    <behaviors:DragOnCanvasBehavior DraggableItem="{Binding}">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                <i:InvokeCommandAction CommandName="StartDrag" />
                            </i:EventTrigger>
                            <i:EventTrigger EventName="PreviewMouseLeftButtonUp">
                                <i:InvokeCommandAction CommandName="StopDrag" />
                            </i:EventTrigger>
                            <i:EventTrigger EventName="PreviewMouseMove">
                                <i:InvokeCommandAction CommandName="Dragging" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </behaviors:DragOnCanvasBehavior>
                </i:Interaction.Behaviors>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

然后,该行为将鼠标事件附加到元素的鼠标处理程序:

public class DragOnCanvasBehavior : Behavior<DependencyObject>
{
    public static readonly DependencyProperty DraggableItemProperty =
        DependencyProperty.RegisterAttached(
            "DraggableItem",
            typeof(IDraggable),
            typeof(DragOnCanvasBehavior),
            new PropertyMetadata(new PropertyChangedCallback((d, e) =>
            {
                ((DragOnCanvasBehavior)d).draggable = (IDraggable)e.NewValue;
            })));

    private IDraggable draggable;

    public DragOnCanvasBehavior()
    {
        this.StartDrag = new RelayCommand((o) =>
        {
            ((UIElement)this.AssociatedObject).MouseLeftButtonDown += this.ElementOnMouseLeftButtonDown;
        });

        this.StopDrag = new RelayCommand((o) =>
        {
            ((UIElement)this.AssociatedObject).MouseLeftButtonUp += this.ElementOnMouseLeftButtonUp;
        });

        this.Dragging = new RelayCommand((o) =>
        {
            ((UIElement)this.AssociatedObject).MouseMove += this.ElementOnMouseMove;
        });
    }

    public IDraggable DraggableItem
    {
        get { return (IDraggable)this.GetValue(DraggableItemProperty); }
        set { this.SetValue(DraggableItemProperty, value); }
    }

    public ICommand Dragging { get; private set; }
    public ICommand StartDrag { get; private set; }
    public ICommand StopDrag { get; private set; }

    // these handle the drag through the IDraggable properties
    // and the mouse event args
    private void ElementOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {}
    private void ElementOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) {}
    private void ElementOnMouseMove(object sender, MouseEventArgs e) {}
}
公共类行为:行为
{
公共静态只读从属属性DragTableItemProperty=
DependencyProperty.RegisterAttached(
“DragableItem”,
类型(IDraggable),
类型(拉票行为),
新PropertyMetadata(新PropertyChangedCallback((d,e)=>
{
(draggable=(IDraggable)e.NewValue;
})));
私人可移动可拖动;
公众拉票行为()
{
this.StartDrag=新的中继命令((o)=>
{
((UIElement)this.AssociatedObject).MouseLeftButtonDown+=this.ElementOnMouseLeftButtonDown;
});
this.StopDrag=新的RelayCommand((o)=>
{
((UIElement)this.AssociatedObject).MouseLeftButtonUp+=this.ElementOnMouseLeftButtonUp;
});
this.Dragging=newrelaycommand((o)=>
{
((UIElement)this.AssociatedObject).MouseMove+=this.ElementOnMouseMove;
});
}
公共IDraggable可拖动项目
{
获取{return(IDraggable)this.GetValue(DraggableItemProperty);}
set{this.SetValue(DragableItemProperty,value);}
}
公共ICommand拖动{get;private set;}
public ICommand StartDrag{get;private set;}
公共ICommand停止拖动{get;private set;}
//这些属性处理通过IDraggable属性的拖动
//和鼠标事件args
私有void元素mouseLeftButtonDown(对象发送方,MouseButtonEventArgs e){}
私有void元素mouseLeftButtonUp(对象发送方,MouseButtonEventArgs e){}
私有void元素mouseMove(对象发送方,MouseEventArgs e){}
}
这是可行的,但我很确定我在这里做错了什么。鼠标事件附加在行为构造函数中,但它们“硬链接”到事件(这意味着我不能将触发器更改为mousedown/up/move以外的内容)


但是,我必须在
元素mousexxx
方法中访问鼠标位置,因此我不确定如何正确操作。

好的,因此您不需要使用
MouseEventArgs
来获取鼠标光标位置,只需使用
System.Windows.Input.mouse
。您也不需要“sender”对象,当使用
行为时
您只需使用
this.associated对象

public DragOnCanvasBehavior()
{
    this.StartDrag = new RelayCommand((o) =>
    {
        this.OnStartDrag();
    });
}

private void OnStartDrag()
{
    // get mouse position
    this.mouseStartPosition = Mouse.GetPosition(Application.Current.MainWindow);

    // access control properties
    ((UIElement)this.AssociatedObject).CaptureMouse();
}