1、效果图:
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、