wpf,后台触发按钮点击以及拖动

触发按钮Click                  
  MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,
                           0, MouseButton.Left);
                    args.RoutedEvent = Button.ClickEvent;
                    btnOkCommand.RaiseEvent(args); 

触发按钮绑定的Command
需要添加UIAutomationProvider 引用
                    ButtonAutomationPeer bam = new ButtonAutomationPeer(btnOkCommand);
                    IInvokeProvider iip = bam.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
                    iip.Invoke();

 

关于拖动

  //WPF设计上的问题,Button.Clicked事件Supress掉了Mouse.MouseLeftButtonDown附加事件等.
                //不加这个Button、TextBox等无法拖动
                if (uiEle is Button||uiEle is TextBox)
                {
                    uiEle.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Element_MouseLeftButtonDown), true);
                    uiEle.AddHandler(Button.MouseMoveEvent, new MouseEventHandler(Element_MouseMove),true);
                    uiEle.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Element_MouseLeftButtonUp), true);
                    continue;
                }
                //
                uiEle.MouseMove += new MouseEventHandler(Element_MouseMove);
                uiEle.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
                uiEle.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);           

 

 

WPF利用代码触发按钮点击操作

WPF拖动总结

 

 

 

 

 

这篇博文总结下WPF中的拖动,文章内容主要包括:

1.拖动窗口

2.拖动控件 Using Visual Studio

  2.1thumb控件

  2.2Drag、Drop(不连续,没有中间动画)

  2.3拖动一个控件

  2.4让一个窗口内的所有(指定的)控件可拖动

3.Expression Blend X实现拖动(Best Practice)

Update: Move and resize controls on a form at runtime (with drag and drop)

小结

1.拖动窗口                        

我们知道,鼠标放在窗口的标题栏上按下就可以拖动窗体。我们要实现在窗口的全部地方或特定地方按下鼠标左键实现拖动。

Winform的做法是,获取鼠标的位置信息,从而设置窗体的位置。

WPF也可以采用Winform类似的方法,但是没有必要,因为有更加单的方法。

复制代码

    
        
            
        
    
复制代码

wpf,后台触发按钮点击以及拖动_第1张图片

有Grid布局的窗口,里面放置了一个Canvas。
要实现在Grid内按下鼠标左键实现窗体拖动/或是Canvas内实现按下鼠标左键实现窗体拖动,代码如下:

复制代码
private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
   base.DragMove();//实现整个窗口的拖动
}

private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
   base.DragMove();
}
复制代码

从上面的代码我们可以看到,DragMove()方法仅用来实现窗体的拖动。

2.拖动控件               

 2.1thumb控件

thumb控件MSDN的描述非常简单:Represents a control that can be dragged by the user.(表示可由用户拖动的控件)。

由DragStarted、DragDelta、DragCompleted着三个事件完成控件的拖动。

给个例子:我们在Canvas中加入如下thumb控件

  

wpf,后台触发按钮点击以及拖动_第2张图片

实现相应的事件,即可完成该控件的拖动工作。

复制代码
private void DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
   Canvas.SetLeft(thumb1,Canvas.GetLeft(thumb1)+e.HorizontalChange);
   Canvas.SetTop(thumb1, Canvas.GetTop(thumb1) + e.VerticalChange);
}

private void DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
   thumb1.Background = Brushes.White;
}

private void DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
   thumb1.Background = Brushes.Red;
}
复制代码

这只是一个简单的示例,我们知道thumb有拇指的意思,代表着很棒的意思。
sukram在2008-08-23在codeproject上发表的WPF Diagram Designer(WPF图形设计器)系列文章(共3篇),被国内很多人Copy过来说是他自己弄的(吐槽:这里省去3K字),其中关于thumb的运用可供参考,thumb可以实现控件的拖动。

2.2 drag、drop(不连续,没有中间动画)

很多控件都有AllowDrop属性:允许放下;和Drop事件。

给出两个例子。

例1:


  

wpf,后台触发按钮点击以及拖动_第3张图片

现在,拖拽label1到label上,把label1的text赋值给label2.实现如下:

复制代码
private void label1_MouseDown(object sender, MouseButtonEventArgs e)
{
    Label lbl = (Label)sender;
    DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Copy);
}
private void tagert_drop(object sender, DragEventArgs e)
{
    ((Label)sender).Content = e.Data.GetData(DataFormats.Text);
}
复制代码

例2:

 界面上有两个Canvas,右面的Canvas里面有一个Rectangle。拖动右面的Rectangle把它拖到左边来,并且保留右边的Rectangle。 

复制代码

    
        
        
            
        
    
复制代码
复制代码
namespace WpfApplicationDrugMove
{
    /// 
    /// Interaction logic for Windowdragdrop.xaml
    /// 
    public partial class Windowdragdrop : Window
    {
        public Windowdragdrop()
        {
            InitializeComponent();

            canvas1.AllowDrop = true;
            rectangle1.PreviewMouseMove += new MouseEventHandler(rectangle1_PreviewMouseMove);
            canvas1.DragOver += new DragEventHandler(canvas1_DragOver);
            canvas1.Drop += new DragEventHandler(canvas1_Drop);
        }     

        void rectangle1_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DataObject data = new DataObject(typeof(Rectangle), rectangle1);
                DragDrop.DoDragDrop(rectangle1, data, DragDropEffects.Copy);
            }
        }

        void canvas1_Drop(object sender, DragEventArgs e)
        {
            IDataObject data = new DataObject();
            data = e.Data;
            if (data.GetDataPresent(typeof(Rectangle)))
            {
                Rectangle rect = new Rectangle();
                rect = data.GetData(typeof(Rectangle)) as Rectangle;
                //canvas2.Children.Remove(rect);
                //canvas1.Children.Add(rect);
                //序列化Control,以深复制Control!!!!
                string rectXaml = XamlWriter.Save(rect);
                StringReader stringReader = new StringReader(rectXaml);
                XmlReader xmlReader = XmlReader.Create(stringReader);
                UIElement clonedChild = (UIElement)XamlReader.Load(xmlReader);
                canvas1.Children.Add(clonedChild);
            }
        }
       

        void canvas1_DragOver(object sender, DragEventArgs e)
        {
            if(!e.Data.GetDataPresent(typeof(Rectangle)))
            {
                e.Effects = DragDropEffects.None;
                e.Handled = true;
            }
            
        }

    }
}
复制代码

效果如下:
wpf,后台触发按钮点击以及拖动_第4张图片

 这个也就回答了博客园的一篇博问:WPF拖拽实现

 虽然这个问题被标记为解决,但是其解决的方法过于丑陋,具体请看DebugLZQ本文代码实现。

 2.3拖动一个控件

 实现和thumb一样的效果,不同于drag/drop,拖动的时候控件跟随鼠标移动。

        
  

wpf,后台触发按钮点击以及拖动_第5张图片

Canvas中又一个控件(Canvas2),实现canvas2的拖动。

实现canvas2的MouseLeftButtonDown、MouseMove、MouseLeftButtonUp事件。

复制代码
Point oldPoint = new Point();
bool isMove = false;
private void canvas2_MouseMove(object sender, MouseEventArgs e)
{
   if (isMove)
   {
       canvas2.Background = Brushes.White;

       FrameworkElement currEle = sender as FrameworkElement;
       double xPos = e.GetPosition(null).X - oldPoint.X + (double)currEle.GetValue(Canvas.LeftProperty);
       double yPos = e.GetPosition(null).Y - oldPoint.Y + (double)currEle.GetValue(Canvas.TopProperty);
       currEle.SetValue(Canvas.LeftProperty, xPos);
       currEle.SetValue(Canvas.TopProperty, yPos);
                
       oldPoint = e.GetPosition(null);
   }
}

private void canvas2_MouseDown(object sender, MouseButtonEventArgs e)
{
   isMove = true;
   oldPoint = e.GetPosition(null);
}

private void canvas2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
   isMove = false;
   canvas2.Background = Brushes.Yellow;
}
复制代码

 2.4让一个窗口内的所有(指定的)控件可拖动

有2.3的基础,现在我们就可以很方便的实现容器内所有控件拖动了。不仅仅局限于Canvas。其实Canvas的绝对定位和其他的容器(如Grid)没多好差别,只不过Canvas使用Left/Top来定位;Grid是用Margin,仅此而已!

1.还是Canvas中的拖动

wpf,后台触发按钮点击以及拖动_第6张图片

复制代码

    
        
复制代码
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplicationDrugMove
{
    /// 
    /// Interaction logic for WindowWPFALLControlDrag.xaml
    /// 
    public partial class WindowWPFALLControlDragInCanvas:Window
    {
        public WindowWPFALLControlDragInCanvas()
        {
            InitializeComponent();

            foreach (UIElement uiEle in LayoutRoot.Children)
            {
                //WPF设计上的问题,Button.Clicked事件Supress掉了Mouse.MouseLeftButtonDown附加事件等.
                //不加这个Button、TextBox等无法拖动
                if (uiEle is Button||uiEle is TextBox)
                {
                    uiEle.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Element_MouseLeftButtonDown), true);
                    uiEle.AddHandler(Button.MouseMoveEvent, new MouseEventHandler(Element_MouseMove),true);
                    uiEle.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Element_MouseLeftButtonUp), true);
                    continue;
                }
                //
                uiEle.MouseMove += new MouseEventHandler(Element_MouseMove);
                uiEle.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
                uiEle.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);                
            }         
        }

        bool isDragDropInEffect = false;
        Point pos = new Point();

        void Element_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement currEle = sender as FrameworkElement;
                double xPos = e.GetPosition(null).X - pos.X + (double)currEle.GetValue(Canvas.LeftProperty);
                double yPos = e.GetPosition(null).Y - pos.Y + (double)currEle.GetValue(Canvas.TopProperty);
                currEle.SetValue(Canvas.LeftProperty, xPos);
                currEle.SetValue(Canvas.TopProperty, yPos);
                pos = e.GetPosition(null);
            }
        } 

        void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            
            FrameworkElement fEle = sender as FrameworkElement;
            isDragDropInEffect = true;
            pos = e.GetPosition(null);
            fEle.CaptureMouse();
            fEle.Cursor = Cursors.Hand;
        }

        void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement ele = sender as FrameworkElement;
                isDragDropInEffect = false;
                ele.ReleaseMouseCapture();
            }
        } 

    }
}
复制代码

注意:需要用AddHandler添加Button.MouseLeftButtonDown等事件,不然无法触发,因为Button.Clicked事件Supress掉了MouseLeftButtonDown。
这样页面上的所有控件就可以随意拖动了。

今天在CodeProject上看到了这篇文章:WPF - Catch Events Even if they are Already Handled,说的是一个事情。

2.Canvas换成Grid。Grid中所有控件可拖动。

复制代码

    
        
复制代码

wpf,后台触发按钮点击以及拖动_第7张图片

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplicationDrugMove
{
    /// 
    /// Interaction logic for WindowWPFALLControlDragMoveInGrid.xaml
    /// 
    public partial class WindowWPFALLControlDragMoveInGrid : Window
    {
        public WindowWPFALLControlDragMoveInGrid()
        {
            InitializeComponent();

            foreach (UIElement uiEle in LayoutRoot.Children)
            {
                if (uiEle is Button || uiEle is TextBox)
                {
                    uiEle.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Element_MouseLeftButtonDown), true);
                    uiEle.AddHandler(Button.MouseMoveEvent, new MouseEventHandler(Element_MouseMove), true);
                    uiEle.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Element_MouseLeftButtonUp), true);
                    continue;
                }
                uiEle.MouseMove += new MouseEventHandler(Element_MouseMove);
                uiEle.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
                uiEle.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);
            } 
        }

        bool isDragDropInEffect = false;
        Point pos = new Point();

        void Element_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement currEle = sender as FrameworkElement;
                double xPos = e.GetPosition(null).X - pos.X + currEle.Margin.Left;
                double yPos = e.GetPosition(null).Y - pos.Y + currEle.Margin.Top;
                currEle.Margin = new Thickness(xPos, yPos, 0, 0);
                pos = e.GetPosition(null);
            }
        }


        void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {

            FrameworkElement fEle = sender as FrameworkElement;
            isDragDropInEffect = true;
            pos = e.GetPosition(null);
            fEle.CaptureMouse();
            fEle.Cursor = Cursors.Hand;
        }

        void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement ele = sender as FrameworkElement;
                isDragDropInEffect = false;
                ele.ReleaseMouseCapture();
            }
        } 

    }
}
复制代码

效果如下:
wpf,后台触发按钮点击以及拖动_第8张图片

 Grid界面中的所有控件可随意拖动。

3.使用Expression Blend实现拖动(Best Practice)

使用如下的一个Behavior:MouseDragElementBehavior

wpf,后台触发按钮点击以及拖动_第9张图片

实现方法非常简单,let's say 我们有个Rectangle,无论在什么容器中,我们要实现其拖动。

直接把这个MouseDragElementBehavior 拖动到Rectangle中即可。

XAML如下:

复制代码

    
                    
            
                
            
        
    
复制代码

(如您所见,DebugLZQ使用的是 Expression Blend 4)。
程序运行正常,Rectangle可随意拖动如下:

wpf,后台触发按钮点击以及拖动_第10张图片wpf,后台触发按钮点击以及拖动_第11张图片

使用Blend借助Behaviors不需要额外的C#代码,最为简洁。

其他的一些Behaviors也非常有用,

如播放MP3:

复制代码

    
        
            
                
                    
                
            
                      
            
                
            
        
    
复制代码

程序可正常运行。

还有如CallMethodAction,ControlStoryboardAction,及MVVM中使用较多的InvokeCommandAction等。

 小结一下:

关于2.2例2中控件的序列化、反序列化! 参考:WPF控件深拷贝:序列化/反序列化

关于Button.MouseLeftButtonDown用C#代码注册的话需要用AddHandler添加,直接添加会被Button.Clicked阻止! 另一种情况是:我们如何捕获一个路由事件,即使这个路由事件已经被标记为e.handled=true。这个很重要!!!参考:WPF捕获事件即使这个事件被标记为Handled  。拖动不局限于Canvas. 

所有方法中,Blend实现最为Clearn.关于Blend 4的快捷键,请参考:A Complete Guide to Expression Blend 4 Shortcut Keys

 

Update1(2014-01-14):

It provide a Winform demo, but It obviously also works for WPF projects.

wpf,后台触发按钮点击以及拖动_第12张图片

Move and resize controls on a form at runtime (with drag and drop)

Posted on CodeProject, By zomorrod.company, 13 Jan 2014

转载于:https://www.cnblogs.com/m7777/p/7110402.html

你可能感兴趣的:(wpf,后台触发按钮点击以及拖动)