【问题标题】:Rearrange CustomControl inside wrappanel in wpf c#在 wpf c# 的 wrappanel 中重新排列 CustomControl
【发布时间】:2016-04-15 08:56:54
【问题描述】:

我正在包装面板内动态创建自定义控件。现在我需要重新排序包装面板内的自定义控件。是否可以使用拖放重新排列包装面板内的自定义控件?

这是我的 XAML 代码

<DockPanel Grid.Column="1" Margin="208,40,1,94" Grid.Row="2"
                   Background="White" AllowDrop="True">
            <ScrollViewer  AllowDrop="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" Width="443">
                <StackPanel Width="443" > 


                    <WrapPanel x:Name="pnl" HorizontalAlignment="Left" 
                        Height="Auto" 
                        VerticalAlignment="Top" Width="480" AllowDrop="True" 
                         />

                     </StackPanel> 
            </ScrollViewer>
        </DockPanel>

我已经尝试将换行面板放在列表中,正如给定答案(Ilan 的答案)所建议的那样,现在我的面板无法在后面的代码中访问。难道我做错了什么?

【问题讨论】:

    标签: c# wpf drag-and-drop rendering wrappanel


    【解决方案1】:

    这里我已经演示了Buttons,你可以根据自己的需要进行修改。

    Xaml

    <WrapPanel x:Name="Pnl" Background="Yellow" Margin="0,0,0,128" Button.DragEnter="Button_DragEnter" Button.MouseRightButtonDown="Button_MouseDown">
        <Button Content="Btn1" AllowDrop="True"/>
        <Button Content="Btn2" AllowDrop="True"/>
        <Button Content="Btn3" AllowDrop="True"/>
    </WrapPanel>
    

    代码

    Button btn_to_drag;
    private void Button_MouseDown(object sender, MouseButtonEventArgs e)
    {
        btn_to_drag = (Button)e.Source;
        DragDrop.DoDragDrop(btn_to_drag, btn_to_drag, DragDropEffects.Move); 
    }
    
    private void Button_DragEnter(object sender, DragEventArgs e)
    {
        Button btn = (Button)e.Source;
        int where_to_drop = Pnl.Children.IndexOf(btn);
        Pnl.Children.Remove(btn_to_drag);
        Pnl.Children.Insert(where_to_drop, btn_to_drag);
    }
    

    使用DataObject 的另一种方法无需btn_to_drag 声明。

    private void Button_MouseDown(object sender, MouseButtonEventArgs e)
    {
        DataObject data = new DataObject(DataFormats.Serializable, (Button)e.Source );
        DragDrop.DoDragDrop((DependencyObject)e.Source, data, DragDropEffects.Move);
    }
    
    private void Button_DragEnter(object sender, DragEventArgs e)
    {
        Button btn_to_move = (Button) e.Data.GetData(DataFormats.Serializable);
                
        int where_to_move = Pnl.Children.IndexOf((UIElement)e.Source);
        int what_to_move = Pnl.Children.IndexOf(btn_to_move);
    
        Pnl.Children.RemoveAt(what_to_move);
        Pnl.Children.Insert(where_to_move, btn_to_move);
    }
    

    【讨论】:

    • 经过几个小时的搜索,感谢这个 awnser 它解决了我的问题:D
    【解决方案2】:

    尝试将您的项目放入 ItemsControl 并将包裹面板设置为控件的 ItemsPanel,然后只需更改项目控件内控件的顺序即可。这是一个简单的示例(将您的控件放入 InputCollection)。

    更新 #2 - DragAndDrop

    Xaml

    Window x:Class="WpfCSItemsControlWithWrappanelSoHelpAttempt.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">
    <Grid x:Name="RootLayout">
        <ListBox x:Name="ListBowWithWrapPanel" Background="Green" Margin="5" 
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Width="250"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ListBox>
        <Button HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Click="ButtonBase_OnClick">Flip</Button>
    </Grid>
    

    代码隐藏(可能的拖放示例)

    public partial class MainWindow : Window
    {
        private readonly ObservableCollection<Shape> _observableCollection;
        private int _coordinator = -1;
        private ListBox _dragSource;
        private Shape _dragedData;
        private Shape _targetData;
        private bool _isInDrag;
    
        public MainWindow()
        {
            InitializeComponent();
    
            _observableCollection = new ObservableCollection<Shape>
            {
                new Ellipse{Name = "C", Width = 50, Height = 50, Fill = Brushes.Tomato},
                new Ellipse{Name = "A", Width = 50, Height = 75, Fill = Brushes.Yellow},
                new Rectangle{Name = "Z", Width = 50, Height = 75, Fill = Brushes.Aqua},
                new Rectangle{Name = "D", Width = 50, Height = 75, Fill = Brushes.Blue},
                new Rectangle{Name = "B", Width = 50, Height = 75, Fill = Brushes.CadetBlue},   
                new Ellipse{Name = "X", Width = 75, Height = 25, Fill = Brushes.Aqua},
            };
    
            ListBowWithWrapPanel.ItemsSource = _observableCollection;
    
            Style itemContainerStyle = new Style(typeof(ListBoxItem));
            itemContainerStyle.Setters.Add(new Setter(AllowDropProperty, true));
            //we have this to handle a possible dragging element
            itemContainerStyle.Setters.Add(new EventSetter(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(ListBowWithWrapPanel_OnPreviewMouseDown)));
            //we have this to start the dragging process
            itemContainerStyle.Setters.Add(new EventSetter(MouseMoveEvent, new MouseEventHandler(MouseMoveHandler)));
            //we have this to stop the where there is no a dragging process
            itemContainerStyle.Setters.Add(new EventSetter(MouseLeftButtonUpEvent, new MouseButtonEventHandler(LeftButtonUp)));
            //we have this to perform the drop(insert the element into a new position)
            itemContainerStyle.Setters.Add(new EventSetter(DropEvent, new DragEventHandler(ListBowWithWrapPanel_OnDrop)));
            //we have this to handle the possible target position
            itemContainerStyle.Setters.Add(new EventSetter(DragOverEvent, new DragEventHandler(OnDragOver)));
            ListBowWithWrapPanel.ItemContainerStyle = itemContainerStyle;
        }
    
        /// <summary>
        /// sort when button click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            var list = _observableCollection.ToList();
            _observableCollection.Clear();
    
            _coordinator *= -1;
    
            list.Sort((shape, shape1) =>
            {
                var name1 = shape.Name;
                var name2 = shape1.Name;
    
                return string.Compare(name1, name2, StringComparison.Ordinal) * _coordinator;
            });
    
            list.ForEach(shape =>
            {
                _observableCollection.Add(shape);
            });
        }
    
        /// <summary>
        /// we have this to handle a possible dragging element
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListBowWithWrapPanel_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var listBoxItem = sender as ListBoxItem;
            if (listBoxItem == null) return;
            _dragSource = listBoxItem.FindParent<ListBox>();
            _dragedData = listBoxItem.DataContext as Shape;
        }
    
        /// <summary>
        /// we have this to start the dragging process
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MouseMoveHandler(object sender, MouseEventArgs e)
        {
            if (_dragedData != null && _isInDrag == false)
            {
                _isInDrag = true;
                DragDrop.DoDragDrop(_dragSource, _dragedData, DragDropEffects.Move);
            }
        }
    
        /// <summary>
        /// we have this to handle the possible target position
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="dragEventArgs"></param>
        private void OnDragOver(object sender, DragEventArgs dragEventArgs)
        {
            var targetPlaceHolder = sender as ListBoxItem;
            if (targetPlaceHolder == null) return;
            _targetData = targetPlaceHolder.DataContext as Shape;
        }
    
        /// <summary>
        /// we have this to stop where there is no a dragging process
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ResumeDragging();
        }
    
        /// <summary>
        /// we have this to perform the drop(insert the element into a new position)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListBowWithWrapPanel_OnDrop(object sender, DragEventArgs e)
        {
            if (Equals(_dragedData, _targetData)) return;
            var targetPlaceHolder = sender as ListBoxItem;
            if (targetPlaceHolder == null) return;
    
            var removedIdx = _observableCollection.IndexOf(_dragedData);
            var targetIdx = _observableCollection.IndexOf(_targetData);
    
            if (removedIdx < targetIdx)
            {
                _observableCollection.Insert(targetIdx + 1, _dragedData);
                _observableCollection.RemoveAt(removedIdx);
            }
            else
            {
                int remIdx = removedIdx + 1;
                if (_observableCollection.Count + 1 > remIdx)
                {
                    _observableCollection.Insert(targetIdx, _dragedData);
                    _observableCollection.RemoveAt(remIdx);
                }
            }
    
            ResumeDragging();
    
        }
    
        private void ResumeDragging()
        {
            _isInDrag = false;
            _dragedData = null;
        }
    }
    

    问候。

    【讨论】:

    • 如您所说,我将包装面板保留在项目控件中。但是现在在后面的代码中无法访问该面板:(为什么会这样?
    • @dahsra 你需要什么才能访问它?请记住,您将项目添加到 ItemsControl,然后将它们输入到包装面板中。
    • 现在我在代码后面的包装面板中动态创建一个用户控件,现在你需要我在 Itemscontrol 中创建那个控件吗??
    • @dahsra common,您只需创建控件,并将其放入 ListBox 项目源中。这完全一样。
    • 已经更新了我的问题,你能告诉我这样做是否正确吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多