WPF 中拖拽控件

1  效果

这里要注意的是要设置

TextBlock 允许拖拽   Canvs 接收拖拽

 2 代码操作

2.1 、 新建一个用户控件 uNodeA.xaml

   <Grid>
        <Grid.RowDefinitions>
            <RowDefinition   />
        </Grid.RowDefinitions>
        <StackPanel>
            <TextBlock  Name="lbl" Text="11#" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Background="Black" />
            <TextBlock Name="btn" Background="Red" Text="我是用户控件A" Height="59" Width="150" />
        </StackPanel>
    </Grid>

后台代码

  /// <summary>
    /// uNodeA.xaml 的交互逻辑
    /// </summary>
    public partial class uNodeA : UserControl
    {
        bool mMoving = false;

        Point mStartPoint = new Point();
        public uNodeA()
        {
            InitializeComponent();
            this.MouseLeftButtonDown += UNode_MouseLeftButtonDown;
            this.MouseLeftButtonUp += UNode_MouseLeftButtonUp;
            this.MouseMove += UNode_MouseMove;
        }
        /// <summary>
        /// 鼠标按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UNode_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            mMoving = true; ;
            mStartPoint = e.GetPosition((IInputElement)sender);
            Mouse.Capture((IInputElement)sender);
        }

        /// <summary>
        /// 鼠标抬起
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UNode_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            mMoving = false; ;
            Mouse.Capture(null);
        }
        /// <summary>
        /// 移动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UNode_MouseMove(object sender, MouseEventArgs e)
        {
            if (mMoving)
            {
               var c = (sender as UserControl);
                var cans = C_ControlFindHelper.FindParent<Canvas>((UIElement)sender);
                var contentControl = C_ControlFindHelper.FindParent<ContentControl>((UIElement)sender);
                var model = (C_NodeLocal)contentControl.Tag;

                Point current = e.GetPosition( cans);
               

                //Canvas cans = (Canvas)(c.Parent);
                //Point current = e.GetPosition(cans);
                ////
                double x = current.X - mStartPoint.X;
                if (x < 0)
                {
                    x = 0;
                }
                if (x > cans.ActualWidth - c.ActualWidth)
                {
                    x = cans.ActualWidth - c.ActualWidth;
                }
                double y = current.Y - mStartPoint.Y;
                if (y < 0)
                {
                    y = 0;
                }
                if (y > cans.ActualHeight - c.ActualHeight)
                {
                    y = cans.ActualHeight - c.ActualHeight;
                }
                model.X =x;
                model.Y =y;

                Console.WriteLine("x"+ model.X + "y="+ model.Y);
                //Canvas.SetLeft(c, x);
                //Canvas.SetTop(c, y);
                //Canvas.SetLeft(c, current.X - mStartPoint.X);
                //Canvas.SetTop(c, current.Y - mStartPoint.Y);
                //c.SetValue(Canvas.LeftProperty, current.X - mStartPoint.X);

                //var c = sender as UserControl;
                //Canvas cans = (Canvas)(c.Parent);
                //Point current = e.GetPosition(cans);
                ////
                //double x = current.X - mStartPoint.X;
                //if (x < 0)
                //{
                //    x = 0;
                //}
                //if (x > cans.ActualWidth - c.ActualWidth)
                //{
                //    x = cans.ActualWidth - c.ActualWidth;
                //}
                //double y = current.Y - mStartPoint.Y;
                //if (y < 0)
                //{
                //    y = 0;
                //}
                //if (y > cans.ActualHeight - c.ActualHeight)
                //{
                //    y = cans.ActualHeight - c.ActualHeight;
                //}
                ////Console.WriteLine("x"+x +"y="+y);
                //Canvas.SetLeft(c, x);
                //Canvas.SetTop(c, y);
                ////Canvas.SetLeft(c, current.X - mStartPoint.X);
                ////Canvas.SetTop(c, current.Y - mStartPoint.Y);
                ////c.SetValue(Canvas.LeftProperty, current.X - mStartPoint.X);

            }
        }
    }

2..2 、新建一个列表页面 uFlowNodeList.xaml

<UserControl x:Class="MachineVision.Core.Views.uFlowNodeList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:local="clr-namespace:MachineVision.Core.Views"
             xmlns:us="clr-namespace:MachineVision.Core.Views"
             xmlns:convers="clr-namespace:MachineVision.Core.Convers"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        <convers:C_DragToDeviceConver  x:Key="node" />
    </UserControl.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Border  Margin="10"   CornerRadius="5"/>
        <ScrollViewer >
            <StackPanel  Background="AliceBlue">
                <UniformGrid  Columns="3" Margin="10">
                    
                    <TextBlock Text="A" Width="40" Height="40" Background="Gray">
                        <i:Interaction.Triggers>
                               <i:EventTrigger EventName="MouseLeftButtonDown">
                                   <i:InvokeCommandAction  Command="{Binding  MouseLeftButtonDownCommand }" 
                                                           CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TextBlock}}}"  />
                               </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBlock>
                    <TextBlock Text="B" Width="40" Height="40" Background="Gray">
                        <i:Interaction.Triggers>
                               <i:EventTrigger EventName="MouseLeftButtonDown">
                                   <i:InvokeCommandAction  Command="{Binding  MouseLeftButtonDownCommand }" 
                                                           CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TextBlock}}}"  />
                               </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </TextBlock>
                </UniformGrid>
            </StackPanel>
        </ScrollViewer>
        <ItemsControl  ItemsSource="{Binding List}" Grid.Column="1">
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Left"  Value="{Binding X}"/>
                    <Setter Property="Canvas.Top"  Value="{Binding Y}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>

            <!--展示模版-->
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas  Background="Transparent" AllowDrop="True">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Drop">
                                <i:CallMethodAction  
                                   TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl},Path=DataContext}" 
                                    MethodName="cans_Drop" 
                                    />

                                <!--<i:InvokeCommandAction  Command="{Binding CansDropCommand }"
                                  CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType= Canvas}}"                      
                                                        />-->
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            
            <!--数据模版-->
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <!--<us:uNode  Width="{Binding Width}"
                              Height="{Binding Height}"/>-->
                    <ContentControl  
                                    Width="{Binding Width}"   Height="{Binding Height}" 
                                    Tag="{Binding}"
                        Content="{Binding NodeName,Converter={StaticResource  node}}" >
                        <!--<i:Interaction.Triggers>
                            <i:EventTrigger EventName="">
                                <i:CallMethodAction />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>-->
                    </ContentControl>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</UserControl>

后代代码 没有

ViewModel 代码

 /// <summary>
    /// 流程节点列表
    /// </summary>
    public class C_FlowNodeListViewModel:C_NavigateViewModel
    {

        /// <summary>
        /// 列表
        /// </summary>	
        private ObservableCollection<C_NodeLocal> mList;
        /// <summary>
        /// 列表
        /// </summary>	
        public ObservableCollection<C_NodeLocal> List
        {
            get { return mList; }
            set { mList = value;  }
        }

        ///// <summary>
        ///// 设置TextBlok控件可以拖拽
        ///// </summary>
        public DelegateCommand<object> MouseLeftButtonDownCommand { get; private set; }

        //public DelegateCommand<object> CansDropCommand { get; private set; }


        /// <summary>
        /// 构造函数
        /// </summary>
        public C_FlowNodeListViewModel()
        {
            MouseLeftButtonDownCommand = new DelegateCommand<object>(Button_MouseLeftButtonDown);
            //CansDropCommand = new DelegateCommand<object>(cans_Drop);
            List = new ObservableCollection<C_NodeLocal>();
            //List.Add(new C_NodeLocal()
            //{
            //    X=50,
            //     Y=50,
            //    Width = 150,
            //    Height=150,
            //        NodeName="A"
            //});
        }

        /// <summary>
        /// 让控件可以拖拽
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //public void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        //{
        //    DragDrop.DoDragDrop((DependencyObject)sender, "eherere", DragDropEffects.Link);
        //}

        //textblok  允许拖拽
        public void Button_MouseLeftButtonDown(object sender)
        {
            TextBlock txt =sender as TextBlock;
            DragDrop.DoDragDrop((DependencyObject)sender, txt.Text, DragDropEffects.Link);
        }


        public void cans_Drop(object sender, DragEventArgs e)
        {
            var data= e.Data.GetData(typeof(string));

            //uNode uNode = new uNode();
            Point point = e.GetPosition((IInputElement)sender);
            List.Add(new C_NodeLocal()
            {
                X = point.X,
                Y = point.Y,
                Width = 150,
                Height = 50,
                NodeName = data.ToString()
            });

            //Canvas.SetLeft(uNode, point.X);
            //Canvas.SetTop(uNode, point.Y);
            //sender.Children.Add(uNode);

            //uNode uNode = new uNode();
            //Point point = e.GetPosition(this.cans);
            //Canvas.SetLeft(uNode, point.X);
            //Canvas.SetTop(uNode, point.Y);
            //cans.Children.Add(uNode);
        }

         
        //public void cans_Drop(object e)
        //{
        //    //  var data= e.Data.GetData(typeof(string));

        //    //uNode uNode = new uNode();
        //    //Point point = e.GetPosition((IInputElement)sender);

        //    //Canvas.SetLeft(uNode, point.X);
        //    //Canvas.SetTop(uNode, point.Y);
        //    //sender.Children.Add(uNode);

        //    //uNode uNode = new uNode();
        //    //Point point = e.GetPosition(this.cans);
        //    //Canvas.SetLeft(uNode, point.X);
        //    //Canvas.SetTop(uNode, point.Y);
        //    //cans.Children.Add(uNode);
        //}







    }

    /// <summary>
    ///
    /// </summary>
    public class C_NodeLocal: BindableBase
    {
        public string NodeName { get; set; }

        /// <summary>
        /// 
        /// </summary>	
        private double mX;
        /// <summary>
        /// 
        /// </summary>	
        public double X
        {
            get { return mX; }
            set { mX = value; RaisePropertyChanged(); }
        }
        /// <summary>
        /// 
        /// </summary>	
        private double mY;
        /// <summary>
        /// 
        /// </summary>	
        public double Y
        {
            get { return mY; }
            set { mY = value; RaisePropertyChanged(); }
        }
        /// <summary>
        /// 
        /// </summary>
        //public double X { get; set; }
        //public double Y { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }

    }

  

2.3 转换器

   /// <summary>
    /// 根据字符串名字创建对应的用户控件
    /// A---用户控件A
    /// B---用户控件B
    /// </summary>
    public class C_DragToDeviceConver : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                string name=value.ToString();
                Type type=Assembly.GetExecutingAssembly().GetType("MachineVision.Core.Controls.uNode" + name);
                if (type != null)
                {
                    return Activator.CreateInstance(type);
                }
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

2.4   查找控件的工具类

 

        public static T FindParent<T>(DependencyObject child, string controlName = "") where T : DependencyObject
        {
            DependencyObject parentObject = VisualTreeHelper.GetParent(child);
            if (parentObject == null) return null;

            T parent = parentObject as T;
            if (parent != null && (string.IsNullOrEmpty(controlName) || (parent as FrameworkElement)?.Name == controlName))
            {
                return parent;
            }
            else
            {
                return FindParent<T>(parentObject, controlName);
            }
        }

 

posted @ 2024-05-28 14:07  陌念  阅读(14)  评论(0)    收藏  举报