hello world

wpf 拖拽 且元素跟随

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace DragDrop
{
    public class DragDropAdorner : Adorner
    {
        public DragDropAdorner(UIElement parent)
            : base(parent)
        {
            IsHitTestVisible = false;
            mDraggedElement = parent as FrameworkElement;
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            if (mDraggedElement != null)
            {
                Win32.POINT screenPos = new Win32.POINT();
                if (Win32.GetCursorPos(ref screenPos))
                {
                    Point pos = PointFromScreen(new Point(screenPos.X, screenPos.Y));

                    //Point elementPos = mDraggedElement.PointFromScreen(new Point());

                    Point elementPos2 = mDraggedElement.PointToScreen(new Point());

                    Rect rect = new Rect(pos.X - elementPos2.X/2, pos.Y- mDraggedElement.ActualHeight/2, mDraggedElement.ActualWidth, mDraggedElement.ActualHeight);
                    drawingContext.PushOpacity(1.0);
                    Brush highlight = mDraggedElement.TryFindResource(SystemColors.HighlightBrushKey) as Brush;
                    if (highlight != null)
                        drawingContext.DrawRectangle(highlight, new Pen(Brushes.Red, 0), rect);
                    drawingContext.DrawRectangle(new VisualBrush(mDraggedElement),
                        new Pen(Brushes.Transparent, 0), rect);
                    drawingContext.Pop();
                }
            }
        }

        FrameworkElement mDraggedElement = null;
    }

    public static class Win32
    {
        public struct POINT { public Int32 X; public Int32 Y; }

        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(ref POINT point);
    }
}

 

前端

<Window x:Class="WpfDragExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfDragExample"
        xmlns:dragDrop="clr-namespace:DragDrop"

        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <DataTemplate x:Key="listBoxTemplate" DataType="{x:Type dragDrop:DataItem}">
            <TextBlock Text="{Binding Header}"/>
        </DataTemplate>
        <HierarchicalDataTemplate x:Key="treeViewTemplate" DataType="{x:Type dragDrop:DataItem}" 
                                  ItemsSource="{Binding Items}">
            <TextBlock Text="{Binding Header}"/>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid x:Name="mTopLevelGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ListBox x:Name="mListBox" Grid.Column="0" ItemsSource="{Binding Source={x:Static dragDrop:Data.Instance}, Path=ListBoxItems}" ItemTemplate="{StaticResource listBoxTemplate}"/>
        <TreeView x:Name="mTreeView" Grid.Column="2" ItemsSource="{Binding Source={x:Static dragDrop:Data.Instance}, Path=TreeViewItems}" ItemTemplate="{StaticResource treeViewTemplate}"
                  AllowDrop="True" DragDrop.DragOver="OnDragOver" DragDrop.Drop="OnDrop"/>
    </Grid>
</Window>

后台

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;
using DragDrop;

namespace WpfDragExample
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            AttachEvents();
        }

        private void AttachEvents()
        {
            mListBox.PreviewMouseMove += OnPreviewListBoxMouseMove;
            mListBox.QueryContinueDrag += OnQueryContinueDrag;
        }

        private void OnPreviewListBoxMouseMove(object sender, MouseEventArgs e)
        {
            if (Mouse.LeftButton != MouseButtonState.Pressed)
                return;

            Point pos = e.GetPosition(mListBox);
            HitTestResult result = VisualTreeHelper.HitTest(mListBox, pos);
            if (result == null)
                return;

            ListBoxItem listBoxItem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit);
            if (listBoxItem == null || listBoxItem.Content != mListBox.SelectedItem || !(mListBox.SelectedItem is DataItem))
                return;

            DragDropAdorner adorner = new DragDropAdorner(listBoxItem);
            mAdornerLayer = AdornerLayer.GetAdornerLayer(mTopLevelGrid);
            mAdornerLayer.Add(adorner);

            DataItem dataItem = listBoxItem.Content as DataItem;
            DataObject dataObject = new DataObject(dataItem.Clone());

            System.Windows.DragDrop.DoDragDrop(mListBox, dataObject, DragDropEffects.Copy);

            mStartHoverTime = DateTime.MinValue;
            mHoveredItem = null;
            mAdornerLayer.Remove(adorner);
            mAdornerLayer = null;
        }

        private void OnQueryContinueDrag(object sender, QueryContinueDragEventArgs e)
        {
            mAdornerLayer.Update();

            UpdateTreeViewExpandingState();
        }

        private void OnDragOver(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;

            Point pos = e.GetPosition(mTreeView);
            HitTestResult result = VisualTreeHelper.HitTest(mTreeView, pos);
            if (result == null)
                return;

            TreeViewItem selectedItem = Utils.FindVisualParent<TreeViewItem>(result.VisualHit);
            if (selectedItem != null)
                selectedItem.IsSelected = true;

            e.Effects = DragDropEffects.Copy;
        }

        private void OnDrop(object sender, DragEventArgs e)
        {
            Point pos = e.GetPosition(mTreeView);
            HitTestResult result = VisualTreeHelper.HitTest(mTreeView, pos);
            if (result == null)
                return;

            TreeViewItem selectedItem = Utils.FindVisualParent<TreeViewItem>(result.VisualHit);
            if (selectedItem == null)
                return;

            DataItem parent = selectedItem.Header as DataItem;
            DataItem dataItem = e.Data.GetData(typeof(DataItem)) as DataItem;
            if (parent != null && dataItem != null)
                parent.Items.Add(dataItem);
        }

        private void UpdateTreeViewExpandingState()
        {
            Win32.POINT point = new Win32.POINT();
            if (Win32.GetCursorPos(ref point))
            {
                Point pos = new Point(point.X, point.Y);
                pos = mTreeView.PointFromScreen(pos);
                HitTestResult result = VisualTreeHelper.HitTest(mTreeView, pos);
                if (result != null)
                {
                    TreeViewItem selectedItem = Utils.FindVisualParent<TreeViewItem>(result.VisualHit);
                    if (selectedItem != null)
                    {
                        if (mHoveredItem != selectedItem)
                        {
                            mHoveredItem = selectedItem;
                            mStartHoverTime = DateTime.Now;
                        }
                        else
                        {
                            if (mHoveredItem.Items.Count > 0 && !mHoveredItem.IsExpanded &&
                                DateTime.Now - mStartHoverTime > TimeSpan.FromSeconds(2))
                                mHoveredItem.IsExpanded = true;
                        }
                    }
                }
            }
        }

        DateTime mStartHoverTime = DateTime.MinValue;
        TreeViewItem mHoveredItem = null;
        AdornerLayer mAdornerLayer = null;
    }

    internal static class Utils
    {
        public static T FindVisualParent<T>(DependencyObject obj) where T : class
        {
            while (obj != null)
            {
                if (obj is T)
                    return obj as T;

                obj = VisualTreeHelper.GetParent(obj);
            }

            return null;
        }
    }
}

数据

using System;
using System.Collections.ObjectModel;

namespace DragDrop
{
    class DataItem : ICloneable
    {
        public DataItem(string header)
        {
            mHeader = header;
        }

        public object Clone()
        {
            DataItem dataItem = new DataItem(mHeader);
            foreach (DataItem item in Items)
                dataItem.Items.Add((DataItem)item.Clone());
            return dataItem;
        }

        public string Header
        {
            get { return mHeader; }
        }

        public ObservableCollection<DataItem> Items
        {
            get
            {
                if (mItems == null)
                    mItems = new ObservableCollection<DataItem>();
                return mItems;
            }
        }

        private string mHeader = string.Empty;
        private ObservableCollection<DataItem> mItems = null;
    }

    class Data
    {
        private static Data mInstance = new Data();

        public static Data Instance
        {
            get { return mInstance; }
        }

        private ObservableCollection<DataItem> GenerateTreeViewItems()
        {
            ObservableCollection<DataItem> items = new ObservableCollection<DataItem>();

            DataItem item1 = new DataItem("Item1");
            item1.Items.Add(new DataItem("SubItem1"));
            item1.Items.Add(new DataItem("SubItem2"));
            item1.Items.Add(new DataItem("SubItem3"));
            item1.Items.Add(new DataItem("SubItem4"));
            items.Add(item1);

            DataItem item2 = new DataItem("Item2");
            item2.Items.Add(new DataItem("SubItem1"));
            item2.Items.Add(new DataItem("SubItem2"));
            items.Add(item2);

            return items;
        }

        private ObservableCollection<DataItem> GenerateListItems()
        {
            ObservableCollection<DataItem> items = new ObservableCollection<DataItem>();
            items.Add(new DataItem("Item1"));
            items.Add(new DataItem("Item2"));
            items.Add(new DataItem("Item3"));
            items.Add(new DataItem("Item4"));
            items.Add(new DataItem("Item5"));
            return items;
        }

        public ObservableCollection<DataItem> TreeViewItems
        {
            get
            {
                if (mTreeViewItems == null)
                    mTreeViewItems = GenerateTreeViewItems();
                return mTreeViewItems;
            }
        }

        public ObservableCollection<DataItem> ListBoxItems
        {
            get
            {
                if (mListBoxItems == null)
                    mListBoxItems = GenerateListItems();
                return mListBoxItems;
            }
        }

        private ObservableCollection<DataItem> mTreeViewItems = null;
        private ObservableCollection<DataItem> mListBoxItems = null;
    }
}

 

拷贝的代码 忘了出处了,有知道的告诉我一下 我注明出处

posted @ 2021-11-26 09:55  我是刹那、  阅读(242)  评论(0编辑  收藏  举报