如何使用c#和wpf使标签可以从一个面板拖动到另一个面板

本文关键字:一个 另一个 拖动 何使用 wpf 标签 | 更新日期: 2023-09-27 18:27:57

我正在尝试使我的文本标签可拖动,当您在c#wpf应用程序中将文本从一个面板拖动到另一个面板时,文本浮动在所有其他元素之上。

我的标签是由一个数组组成的,其中包含这样一个故事中的单词:

foreach (string word in lines)
{
   Label myLabel = new Label();
   myLabel.Content = word;
   myLabel.Name = "lbl" + x;
   myLabel.FontSize = 30;
   myLabel.Margin = new Thickness(0, -10, 0, -10);
   myLabel.FontFamily = new FontFamily("Segoe Print");
   myLabel.MouseDown += new MouseButtonEventHandler(myLabel_MouseDown);
   myLabel.MouseMove += new MouseEventHandler(myLabel_MouseMove);
   myLabel.MouseLeftButtonUp += new MouseButtonEventHandler(myLabel_MouseLeftButtonUp);
   myLabel.MouseUp += new MouseButtonEventHandler(myLabel_MouseUp);
   leftPanel.Children.Add(myLabel);
   myLabelWidth.Add(myLabel.ActualWidth);
   x++;
}

在我的活动中,我试图弄清楚是什么将标签从包含面板之外移动到另一个面板中。在wpf中,我甚至不知道如何将标签位置设置为按住鼠标并移动的鼠标位置。

我有一些东西根本不起作用,但看起来像这样:

void myLabel_MouseMove(object sender, MouseEventArgs s)
{
   Label myLabel = sender as Label
   if(e.LeftButton == MouseButtonState.Pressed)
   {
      myLabel.Left = e.GetPosition(this).X;
      myLabel.Top= e.GetPosition(this).Y;
   }
}

由于这太遥远了,我真的没有走得更远。感谢您的帮助。

谢谢。

如何使用c#和wpf使标签可以从一个面板拖动到另一个面板

在WPF中有很多实现拖放的方法,但没有一种是微不足道的。例如,您可以:

  • 将拇指添加到画布并实现dragstart、dragcomplete和dragdelta
  • 使用装饰。好文章在这里
  • 使用RenderTransform并创建TranslateTransform来移动控件。并在窗口/用户控件上手动实现mousedown、mousemove和mouseup

以下代码使用运行时生成的Labels的RenderTransform属性在用户用鼠标拖动标签时在屏幕上移动标签。我的示例的一个限制是,不能将其他转换应用于标签,因为它将被覆盖。考虑使用TransformGroup。

Xaml

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Background="Gray" PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown" PreviewMouseMove="Window_PreviewMouseMove" PreviewMouseLeftButtonUp="Window_PreviewMouseLeftButtonUp">
<Grid>
<ItemsControl ItemsSource="{Binding LabelsCollection}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Label HorizontalAlignment="Center" Content="{Binding}"></Label>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

代码隐藏

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private List<DependencyObject> _hitResultsList = new List<DependencyObject>();
    private Point _currentlyDraggedMouseOffset;
    private Label _currentlyDragged;
    private ObservableCollection<string> _labelsCollection;
    public event PropertyChangedEventHandler PropertyChanged;
    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
        LabelsCollection = new ObservableCollection<string>();
        for (int i = 1; i <= 10; i++)
        {
            LabelsCollection.Add("Label " + i);
        }
    }
    public ObservableCollection<string> LabelsCollection
    {
        get { return _labelsCollection; }
        set
        {
            _labelsCollection = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("LabelsCollection"));
            }
        }
    }
    private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (_currentlyDragged != null)
        {                
            var mousePos = e.GetPosition(this);
            _currentlyDragged.RenderTransform = new TranslateTransform(mousePos.X - _currentlyDraggedMouseOffset.X, mousePos.Y - _currentlyDraggedMouseOffset.Y);
        }
    }
    private void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        _currentlyDragged = null;
        ReleaseMouseCapture();
    }
    private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        CaptureMouse();
        Point pt = e.GetPosition((UIElement)sender);
        _hitResultsList.Clear();
        VisualTreeHelper.HitTest(this, null,
            new HitTestResultCallback(MyHitTestResult),
            new PointHitTestParameters(pt));
        if (_hitResultsList.Count > 0)
        {
            foreach (DependencyObject d in _hitResultsList)
            {
                var parent = VisualTreeHelper.GetParent(d);
                if (parent != null && parent is Label)
                {
                    _currentlyDragged = parent as Label;
                    if (_currentlyDragged.RenderTransform is TranslateTransform)
                    {
                        _currentlyDraggedMouseOffset.X = e.GetPosition(this).X - ((TranslateTransform)_currentlyDragged.RenderTransform).X;
                        _currentlyDraggedMouseOffset.Y = e.GetPosition(this).Y - ((TranslateTransform)_currentlyDragged.RenderTransform).Y;
                    }
                    else
                    {
                        _currentlyDraggedMouseOffset.X = pt.X;
                        _currentlyDraggedMouseOffset.Y = pt.Y;
                    }
                    return;
                }
            }
        }
        _currentlyDragged = null;
    }
    // Return the result of the hit test to the callback. 
    public HitTestResultBehavior MyHitTestResult(HitTestResult result)
    {
        _hitResultsList.Add(result.VisualHit);
        return HitTestResultBehavior.Continue;
    }
}

在WPF拖放中,活动的中心是DoDragDrop方法,如果您希望在应用程序中具有拖放功能,则需要使用它。

这是一个相对直接的过程(只要你不是正统的MVVM)开始。。。

确定要实施的控制。在他们的方言中,它被称为"DragSource"。并将您的投递区域设置为AllowDrop=true。

然后挂接控件的MouseDown事件并调用DoDragDrop。之后,就需要挂接四个回调:DragEnter、DragOver、DragLeave和Drop。这些方法控制隐喻在用户界面上的可视化方式。

如果你想参考的话,这里有一条步行路线http://msdn.microsoft.com/en-us/library/za0zx9y0.aspx

如果你是一个正统的MVVM人员,你可以使用附加的行为来重新设计代码背后的挂钩。