在wpf c#中重新排列wrapppanel中的CustomControl

时间:2016-04-15 08:56:54

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

我在一个wrappanel中动态创建一个customcontrol。现在我需要重新排序wrappanel内的自定义控件。是否可以使用拖放重新排列wrappanel内的自定义控件?

这是我的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的回答)所示,现在我的面板无法在后面的代码中访问。我做错了什么?

enter image description here

2 个答案:

答案 0 :(得分:4)

Drag Drop in a WrapPanel

我已在此处演示if($result->num_rows>0),您可以根据需要对其进行修改。

的Xaml

Buttons

代码

<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

答案 1 :(得分:1)

尝试将项目放入ItemsControl并将wrappanel设置为控件的ItemsPanel,然后只更改items控件内控件的顺序。这是一个简单的例子(将你的控件放入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;
    }
}

问候。