ItemsControl拖放 [英] ItemsControl Drag and Drop

查看:178
本文介绍了ItemsControl拖放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ItemControl与DataTemplate绑定到一个ObservableCollection的整数。

 < ItemsControl Name =DimsContainer ItemTemplate ={StaticResource DimensionsTemplate}> 
< ItemsControl.ItemsPanel>
< ItemsPanelTemplate>
< StackPanel Orientation =Horizo​​ntal/>
< / ItemsPanelTemplate>
< /ItemsControl.ItemsPanel>
< / ItemsControl>

在Windows资源中:

 < Window.Resources> 
< DataTemplate x:Key =DimensionsTemplate>
< TextBlock Text ={Binding}
Padding =5
VerticalAlignment =Center
FontSize =32/>
< / DataTemplate>
< /Window.Resources>

我试图实现拖放ItemsControl内的项目的能力(即能够重新排序整数)。有没有人有一个简单的例子,如何做到这一点?我连接了PreviewMouseMove,DragEnter和Drop事件。问题是我无法确定如何确定哪个项目被拖动以及拖动到哪个项目。看来整个ItemsControl都被传入事件。

解决方案

这是一个我如何做到的例子。 p>

XAML:

 < Window.DataContext> 
< local:MyViewModel />
< /Window.DataContext>

< Grid>
< ScrollViewer>
< ListView ItemsSource ={Binding MyData}Horizo​​ntalAlignment =StretchName =listviewScrollViewer.PanningMode =VerticalOnly>
< ListView.ItemTemplate>
< DataTemplate>
< Button Content ={Binding}
Command ={Binding DataContext.MyCommand,RelativeSource = {RelativeSource AncestorType = ItemsControl}}
CommandParameter ={Binding}
Margin =5 2Width =150Height =50
FontSize =30/>
< / DataTemplate>
< /ListView.ItemTemplate>
< ListView.Resources>
< Style TargetType =Button>
< EventSetter Event =PreviewMouseMoveHandler =PreviewMouseMove/>
< EventSetter Event =DropHandler =Drop/>
< Setter Property =AllowDropValue =True/>
< / Style>
< /ListView.Resources>
< / ListView>
< / ScrollViewer>
< / Grid>



ViewModel:

  class MyViewModel 
{
public MyViewModel()
{
MyCommand = new ICommandImplementation();
}

public ObservableCollection< string> MyData
{
get
{
return new ObservableCollection< string>(new string [] {
one,two,three, ,五,六,七,八,九,十,二十八,十一,十四,十五, 十六,十七,十八,十九,二十,
});
}
}

public ICommand MyCommand {get;私人集合}

私有类ICommandImplementation:ICommand
{
public bool CanExecute(object parameter){return true; }
public event EventHandler CanExecuteChanged;
public void Execute(object parameter){System.Windows.MessageBox.Show(Button clicked!+(parameter ??).ToString()); }
}
}

事件: em>

  private void Drop(object sender,DragEventArgs e)
{
var source = e.Data.GetData(Source)as string;
if(source!= null)
{
int newIndex = listview.Items.IndexOf((发件人为Button).Content);
var list = listview.ItemsSource as ObservableCollection< string> ;;;
list.RemoveAt(list.IndexOf(source));
list.Insert(newIndex,source);
}
}

private void PreviewMouseMove(object sender,MouseEventArgs e)
{
if(e.LeftButton == MouseButtonState.Pressed)
{
Task.Factory.StartNew(new Action(()=>
{
Thread.Sleep(500);
App.Current.Dispatcher.BeginInvoke Action(()=>
{
if(e.LeftButton == MouseButtonState.Pressed)
{
var data = new DataObject();
data。 SetData(Source,(sender as Button).Content);
DragDrop.DoDragDrop(发件人为DependencyObject,data,DragDropEffects.Move);
e.Handled = true;
}
}),null);
}), CancellationToken.None);
}
}

上面的例子是一个复杂的原因, code>列表是一个按钮按钮 点击我也要做一些动作。 您的情况相对容易。


对许多开发者来说,丢弃可能会令人困惑。但是低于
是一些要点:


  1. 使用 PreviewMouseMove 事件实际上开始一个拖动和处理程序使用 DragDrop.DoDragDrop 事件来提高 DragDrop 相关
    事件和游标发件人参数是
    的元素,目前在这种情况下,目标是$ code> UIElement 那是
    被拖动。


  2. 使用 DragEnter &如果要更改 Mouse 当前正在拖动的元素的视觉效果, DragOver 事件。 发件人
    参数是当前拖动的元素,只是
    结束拖拽状态。


  3. 使用删除事件来处理已删除的元素。 发件人参数是Drop发生的元素。


  4. 使用 DataObject 对象在这些事件之间传递信息。该类的 SetData 方法用于在此中添加数据。这个方法
    有两个参数,它们像 key-value 对一样工作。一旦设置你
    可以通过使用
    GetData 在下一个被调用的事件 DragDrop 通过传递作为参数。 (即
    e.Data.GetData(Source)



这里是一个相关的帖子。


I have an ItemsControl with a DataTemplate that is bound to an ObservableCollection of integers.

<ItemsControl Name="DimsContainer" ItemTemplate="{StaticResource DimensionsTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
</ItemsControl>

And in the Windows Resources:

<Window.Resources>
    <DataTemplate x:Key="DimensionsTemplate" >
        <TextBlock Text="{Binding}"
                       Padding="5"
                       VerticalAlignment="Center"
                       FontSize="32"/>
    </DataTemplate>
</Window.Resources>

I'm trying to implement the ability to drag and drop items within the ItemsControl (i.e. to be able to reorder the integers). Does anyone have a simple example of how to do this? I hooked up the PreviewMouseMove, DragEnter and Drop events. The problem is that I can't figure out how to determine which item is being dragged and where it is dragged to. It seems that the entire ItemsControl gets passed into the events.

解决方案

Here is an example how I've done it.

XAML:

<Window.DataContext>
    <local:MyViewModel />
</Window.DataContext>

<Grid>
    <ScrollViewer>
        <ListView ItemsSource="{Binding MyData}" HorizontalAlignment="Stretch" Name="listview" ScrollViewer.PanningMode="VerticalOnly">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding}"
                        Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
                        CommandParameter="{Binding}"
                        Margin="5 2" Width="150" Height="50"
                        FontSize="30" />
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.Resources>
                <Style TargetType="Button">
                    <EventSetter Event="PreviewMouseMove" Handler="PreviewMouseMove" />                        
                    <EventSetter Event="Drop" Handler="Drop" />                       
                    <Setter Property="AllowDrop" Value="True" />                        
                </Style>
            </ListView.Resources>
        </ListView>
    </ScrollViewer>
</Grid>

ViewModel:

 class MyViewModel
{
    public MyViewModel()
    {
        MyCommand = new ICommandImplementation();
    }

    public ObservableCollection<string> MyData
    {
        get
        {
            return new ObservableCollection<string>(new string[]{
            "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
            "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"
            });
        }
    }

    public ICommand MyCommand { get; private set; }

    private class ICommandImplementation : ICommand
    {
        public bool CanExecute(object parameter) { return true; }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter) { System.Windows.MessageBox.Show("Button clicked! " + (parameter ?? "").ToString()); }
    }
}

Events:

 private void Drop(object sender, DragEventArgs e)
    {
        var source = e.Data.GetData("Source") as string;
        if (source != null)
        {
            int newIndex = listview.Items.IndexOf((sender as Button).Content);
            var list = listview.ItemsSource as ObservableCollection<string>;
            list.RemoveAt(list.IndexOf(source));
            list.Insert(newIndex, source);
        }
    }

    private void PreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            Task.Factory.StartNew(new Action(() =>
                {
                    Thread.Sleep(500);
                    App.Current.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            if (e.LeftButton == MouseButtonState.Pressed)
                            {                                    
                                var data = new DataObject();
                                data.SetData("Source", (sender as Button).Content);
                                DragDrop.DoDragDrop(sender as DependencyObject, data, DragDropEffects.Move);
                                e.Handled = true;
                            }
                        }), null);
                }), CancellationToken.None);
        }           
    }

Above example is a little complex cause every item of list is a Button and on Button click I also have to do some action. Your case is relatively easy.

Drag & Drop can be confusing for many developers. But below are the some key points how to do it:

  1. Use PreviewMouseMove event to actually start a drag and in handler use DragDrop.DoDragDrop event to raise DragDrop related events and Cursors. sender argument is the element that has captured the mouse currently in this case the UIElement that is being dragged.

  2. Use DragEnter & DragOver event if want to change the visual of element over which the Mouse is currently dragging. sender argument is the element that has currently dragged over / that just ended drag over situation.

  3. Use Drop event to handle the dropped element. sender argument is the element on which the Drop happened.

  4. Use DataObject object to pass info between these events. SetData method of the class is used to add data in this. This method has two arguments, and they work like key-value pair. Once set you can get this data in next called event of DragDrop by using GetData method by passing the key as argument. (i.e. e.Data.GetData("Source"))

Here is a relative post.

这篇关于ItemsControl拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆