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

浙公网安备 33010602011771号