簡體   English   中英

如何使用c#和wpf使標簽從一個面板拖動到另一面板?

[英]How can I make labels draggable from one panel to another with c# and wpf?

我正在嘗試使文本標簽可拖動,在ac#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;
   }
}

既然到目前為止還很遙遠,我還沒有進一步了解。 任何幫助表示贊賞。

謝謝。

在WPF中實現拖放的方法有很多種,但沒有一種是很簡單的。 例如,您可以:

  • 將“ Thumbs”添加到畫布並實現dragstart,dragcomplete和dragdelta
  • 使用裝飾品。 好文章在這里
  • 使用RenderTransform並創建一個TranslateTransform來移動控件。 並在窗口/用戶控件上手動實現mousedown,mousemove和mouseup。

以下代碼使用運行時生成的標簽的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/zh-cn/library/za0zx9y0.aspx

如果您是正統的MVVM人員,則可以使用附加的行為來重新設計背后代碼中的掛鈎。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM