2016-04-15 7 views
2

ラッパーパネルの中にカスタムコントロールを動的に作成しています。今私は、ラッパーパネルの中にあるカスタムコントロールの並べ替えが必要です。ドラッグアンドドロップを使用してラッパーパネル内のカスタムコントロールを再配置することは可能ですか?ここでwpfでラッパーパネル内のCustomControlを並べ替えます。C#

は私の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> 

は、それが与えられた答え(宜蘭の答え)によって提案されたとして、私は、リスト内のラップパネルを入れて試してみた、そして今、私のパネルがでアクセス可能ではないですコードの背後にある。 AM何かが間違っている?

enter image description here

答えて

1

のItemsControlにあなたの項目を入れて、コントロールのItemsPanelするwrappanelを設定し、そしてちょうど項目コントロール内のコントロールの順序を変更してください。ここでは簡単な例を示します(コントロールを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; 
    } 
} 
(ドラッグアンドドロップの可能な例)

よろしく。ここで

+0

あなたは今、そのパネルは、背後にあるコードにアクセスできませんでしたあなたはそれがアクセスできるようにする必要があるために何を、なぜそのように? – Arshad

+0

@dahsraを:(said.Butように私は項目コントロール内に私のラップパネルを保持?保管してください – Ilan

+0

今、私は、コードコントロールでそのラップパネルの中に動的にusercontrolを作成しています。今ではItemsControlの中でそのコントロールを作成する必要がありますか? – Arshad

2

Drag Drop in a WrapPanel

私はあなたのニーズに合わせてそれを変更することができ、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); 
} 

btn_to_drag宣言の必要性を取り除くDataObjectを使用して別のアプローチ。

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); 
} 
関連する問題