WPF拖动DataGrid中的数据到ListBox

时间:2021-09-25 15:50:46
原文: WPF拖动DataGrid中的数据到ListBox

1、效果图:

 

WPF拖动DataGrid中的数据到ListBox

 

2、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" Loaded="Window_Loaded">
    <Grid>
        <ListBox Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="m_ListBox" VerticalAlignment="Top" Width="148" SelectionMode="Single"  AllowDrop="True" Drop="m_ListBox_Drop" DragOver="m_ListBox_DragOver">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Id, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
                        <TextBlock Text="{Binding Path=Name, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
                        <TextBlock Text="{Binding Path=ChildCount, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
                        <Button Content="展示" Tag="{Binding}" Name="m_ListBoxButton" Click="m_ListBoxButton_Click" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <DataGrid AutoGenerateColumns="False" Height="287" HorizontalAlignment="Left" Margin="181,12,0,0" Name="m_DataGrid" VerticalAlignment="Top" Width="299" AllowDrop="True" SelectionMode="Extended"  PreviewMouseLeftButtonDown="m_DataGrid_PreviewMouseLeftButtonDown">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Id}" IsReadOnly="True" />
                <DataGridTextColumn Binding="{Binding Name}" IsReadOnly="True" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

 

3、CS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 System.Collections.ObjectModel;
using System.ComponentModel;

namespace WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<Person> listBoxList = new ObservableCollection<Person>();
        private Person m_SelectedListBoxPerson;
        private Button m_SelectedListBoxButton;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Person person = new Person() { Id = "01", Name = "未分配" };
            listBoxList.Add(person);
            listBoxList.Add(new Person() { Id = "a1", Name = "a11" });
            listBoxList.Add(new Person() { Id = "a2", Name = "a22" });
            //初始化数据
            person.Children.Add(new Person() { Id = "1", Name = "001" });
            person.Children.Add(new Person() { Id = "2", Name = "002" });
            person.Children.Add(new Person() { Id = "3", Name = "003" });
            person.Children.Add(new Person() { Id = "4", Name = "004" });
            person.Children.Add(new Person() { Id = "5", Name = "005" });
            person.Children.Add(new Person() { Id = "6", Name = "006" });
            person.Children.Add(new Person() { Id = "7", Name = "007" });
            person.Children.Add(new Person() { Id = "8", Name = "008" });
            person.Children.Add(new Person() { Id = "9", Name = "009" });
            person.Children.Add(new Person() { Id = "10", Name = "010" });

            //控件加载数据
            this.m_ListBox.ItemsSource = listBoxList;
        }
        private void m_DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point pos = e.GetPosition(m_DataGrid);
            HitTestResult result = VisualTreeHelper.HitTest(m_DataGrid, pos);
            DataGrid dataGrid = this.FindVisualParent<DataGrid>(result.VisualHit);
            if (dataGrid == null || dataGrid.SelectedItems.Count <= 0)
            {
                return;
            }

            List<Person> list = new List<Person>();
            for (int i = 0; i < dataGrid.SelectedItems.Count; i++)
            {
                if (dataGrid.SelectedItems[i] is Person)
                {
                    list.Add(dataGrid.SelectedItems[i] as Person);
                }
            }
            DragDrop.DoDragDrop(m_DataGrid, list, DragDropEffects.Move);
        }
        private void m_ListBox_Drop(object sender, DragEventArgs e)
        {
            Point pos = e.GetPosition(m_ListBox);
            HitTestResult result = VisualTreeHelper.HitTest(m_ListBox, pos);
            if (result == null)
            {
                return;
            }
            ListBox listBox = this.FindVisualParent<ListBox>(result.VisualHit);
            if (listBox == null || listBox.SelectedItem == null)
            {
                return;
            }

            List<Person> persons = e.Data.GetData(typeof(List<Person>)) as List<Person>;
            if (persons != null)
            {
                foreach (var item in persons)
                {
                    Person person = listBox.SelectedItem as Person;
                    person.Children.Add(item);
                    person.ChangeChildCount();

                    m_SelectedListBoxPerson.Children.Remove(item);
                    m_SelectedListBoxPerson.ChangeChildCount();
                }
            }
        }
        private void m_ListBox_DragOver(object sender, DragEventArgs e)
        {
            Point pos = e.GetPosition(m_ListBox);
            HitTestResult result = VisualTreeHelper.HitTest(m_ListBox, pos);
            if (result == null)
            {
                return;
            }
            ListBoxItem listBoxItem = this.FindVisualParent<ListBoxItem>(result.VisualHit);
            if (listBoxItem == null || listBoxItem.Content == null || !(listBoxItem.Content is Person))
            {
                return;
            }

            m_ListBox.SelectedItem = listBoxItem.Content;
            m_ListBox.Focus();
        }
        private void m_ListBoxButton_Click(object sender, RoutedEventArgs e)
        {
            if (m_SelectedListBoxButton != null)
            {
                m_SelectedListBoxButton.IsEnabled = true;
                m_SelectedListBoxButton.Content = "展示";
            }
            m_SelectedListBoxButton = sender as Button;
            m_SelectedListBoxButton.Content = "待分配数据集合";
            m_SelectedListBoxButton.IsEnabled = false;
            m_ListBox.SelectedItem = m_SelectedListBoxButton.Tag;
            m_ListBox.Focus();
            m_SelectedListBoxPerson = m_ListBox.SelectedItem as Person;
            this.m_DataGrid.ItemsSource = m_SelectedListBoxPerson.Children;
        }

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

    class Person : INotifyPropertyChanged
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public int ChildCount 
        {
            get {
                return this.Children.Count;
            }
        }
        public ObservableCollection<Person> Children { get; set; }
        public void ChangeChildCount()
        {

            this.Changed("ChildCount");
        }
       
        public Person() 
        {
            this.Children = new ObservableCollection<Person>();
        }

        #region 属性更改通知
        public event PropertyChangedEventHandler PropertyChanged;
        private void Changed(string PropertyName)
        {
            if (this .PropertyChanged != null)
                this.PropertyChanged(this , new PropertyChangedEventArgs(PropertyName));
        }
        #endregion
    }
}

 

 

4、