如何在运行时通过在WPF中使用拖放功能将列表框动态添加到“包装”面板

时间:2018-07-16 07:36:45

标签: c# wpf

这是我的代码,右侧有一个列表框,该列表框项已添加到网格内的另一个列表框项。通过使用上下文菜单动态添加网格。直到一切正常。但是现在我想在运行时将整个列表而不是列表项动态地移动到网格中。请任何人指导我拖动整个列表,并将其动态地在运行时放置到网格中。

  <Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <WrapPanel
            x:Name="mainPanel"
            Grid.Column="0"
            Background="#F0F0F0"
            ScrollViewer.VerticalScrollBarVisibility="Auto">
            <WrapPanel.ContextMenu>
                <ContextMenu>
                    <MenuItem Click="MenuItem_Click" Header="Add Pabel" />
                </ContextMenu>
            </WrapPanel.ContextMenu>
        </WrapPanel>

        <ListBox
            Name="memberCollection"
            Grid.Column="1"
            Width="150"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch"
            PreviewMouseLeftButtonDown="memberCollection_PreviewMouseLeftButtonDown">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Name="Name" Content="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Grid>

隐藏代码

ObservableCollection<Member> member = new ObservableCollection<Member>();

    public MainWindow()
    {
        InitializeComponent();

        member.Add(new Member { Name = "Karthick", ID = "20011", Address = "10, MainRoad, Chennai" });
        member.Add(new Member { Name = "Suresh", ID = "20012", Address = "11, MainRoad, Madurai" });
        member.Add(new Member { Name = "Arun", ID = "20013", Address = "12, MainRoad, Selam" });
        member.Add(new Member { Name = "Gokul", ID = "20014", Address = "13, MainRoad, Coimbature" });
        member.Add(new Member { Name = "Vishnu", ID = "20015", Address = "14, MainRoad, Goa" });

        memberCollection.ItemsSource = member;
    }

    private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        Grid panel = new Grid();
        panel.MinHeight = 150;
        panel.MinWidth = 150;
        panel.Height = 150;
        panel.Width = 150;
        panel.Margin = new Thickness(15,15,0,10);

        Grid gridDrop = new Grid()
        {
            Background = Brushes.White,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch                
        };

        gridDrop.Drop += grid_Drop;

        var panelTemplate = new DataTemplate();            
        var stackPanel = new FrameworkElementFactory(typeof(StackPanel));
        stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);            

        var name = new FrameworkElementFactory(typeof(Label));            
        name.SetBinding(Label.ContentProperty, new Binding("Name"));
        var id = new FrameworkElementFactory(typeof(Label));
        id.SetBinding(Label.ContentProperty, new Binding("ID"));
        var address = new FrameworkElementFactory(typeof(Label));
        address.SetBinding(Label.ContentProperty, new Binding("Address"));
        stackPanel.AppendChild(name);
        stackPanel.AppendChild(id);
        stackPanel.AppendChild(address);

        panelTemplate.VisualTree = stackPanel;            

        ListBox listBox = new ListBox()
        {
            AllowDrop = true,
            ItemTemplate = panelTemplate
        };         

        gridDrop.Children.Add(listBox);
        panel.Children.Add(gridDrop);
        mainPanel.Children.Add(panel);

        DataContext = new Member();
    }       

    private void memberCollection_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        object selectedMember = memberCollection.SelectedItem as Member;
        if (selectedMember != null)
        {
            DragDrop.DoDragDrop(memberCollection, selectedMember, DragDropEffects.Move);                
        }
    }

    private void grid_Drop(object sender, RoutedEventArgs e)
    {
        ListBox listContent = e.Source as ListBox;
        if (listContent != null)
            Console.WriteLine("", Grid.GetColumn(listContent), Grid.GetRow(listContent));

        DataObject item = (((DragEventArgs)e).Data) as DataObject;

        object Target = ((Grid)(sender)).DataContext;

        if (Target != null)
        {
            object listItem = item.GetData(Target.GetType());
            listContent.Items.Add(listItem);
        }                                        
    }

1 个答案:

答案 0 :(得分:0)

如果您只想移动整个列表并为每个Member创建一个图块,那么这是一种方法:

首先,您应该简化模板并将其放在XAML中。 XAML在处理任何类型的模板方面都比背后的代码有效得多

对于您的左侧主面板:

        <ItemsControl x:Name="mainPanel" Grid.Column="0" ItemsSource="{Binding}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Background="#F0F0F0"  AllowDrop="True"  Drop="mainPanel_Drop">
                        <WrapPanel.ContextMenu>
                            <ContextMenu>
                                <MenuItem Click="MenuItem_Click" Header="Add Panel" />
                            </ContextMenu>
                        </WrapPanel.ContextMenu>
                    </WrapPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical" Background="White"  AllowDrop="True" Margin="15,15,0,10" Width="150" MinWidth="150" Height="150" MinHeight="150">
                        <Label Content="{Binding Name}"/>
                        <Label Content="{Binding ID}"/>
                        <Label Content="{Binding Address}"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

对于您的列表(没有太大变化)

        <ListBox
        Name="memberCollection"
        Grid.Column="1"
        Width="150"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        ItemsSource="{Binding}"
        PreviewMouseLeftButtonDown="memberCollection_PreviewMouseLeftButtonDown">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Name="memberName" Content="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

我添加了两个ObservableCollection来管理数据

    ObservableCollection<Member> member = new ObservableCollection<Member>();
    ObservableCollection<Member> mainPanelMembers = new ObservableCollection<Member>();

    public MainWindow()
    {
        InitializeComponent();

        member.Add(new Member { Name = "Karthick", ID = "20011", Address = "10, MainRoad, Chennai" });
        member.Add(new Member { Name = "Suresh", ID = "20012", Address = "11, MainRoad, Madurai" });
        member.Add(new Member { Name = "Arun", ID = "20013", Address = "12, MainRoad, Selam" });
        member.Add(new Member { Name = "Gokul", ID = "20014", Address = "13, MainRoad, Coimbature" });
        member.Add(new Member { Name = "Vishnu", ID = "20015", Address = "14, MainRoad, Goa" });

        memberCollection.DataContext = member;
        mainPanel.DataContext = mainPanelMembers;
    }

然后,创建新的Tile更加简单:

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    mainPanelMembers.Add(new Member());
}

如果要复制整个列表,则必须将整个ObservableCollection提供给DragDrop管理器:

    private void memberCollection_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        object collectionDataContext = memberCollection.DataContext;
        if (collectionDataContext != null)
        {
            DataObject dragData = new DataObject("DataContext", collectionDataContext);
            DragDrop.DoDragDrop(memberCollection, dragData, DragDropEffects.Move);
        }
    }

当您删除它时,您可以简单地一个接一个地添加成员。您也可以之前(但我没有)清除收藏集:

    private void mainPanel_Drop(object sender, DragEventArgs e)
    {
        DataObject item = e.Data as DataObject;
        object listItem = item.GetData("DataContext") as IEnumerable<Member>;

        if (listItem != null)
        {
            foreach (Member member in (IEnumerable<Member>)listItem)
            {
                ((ObservableCollection<Member>)mainPanel.DataContext).Add(member);
            }

        }
    }

我不确定我是否很好地了解了您想要什么...我仍然不知道您如何使用Tile创建。 让我知道您是否需要做一些不同的事情。