首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ItemsControl拖放

ItemsControl拖放
EN

Stack Overflow用户
提问于 2010-08-20 21:17:56
回答 1查看 12.1K关注 0票数 12

我有一个ItemsControl,它的DataTemplate绑定到整数的ObservableCollection上。

代码语言:javascript
复制
<ItemsControl Name="DimsContainer" ItemTemplate="{StaticResource DimensionsTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
</ItemsControl>

在Windows参考资料中:

代码语言:javascript
复制
<Window.Resources>
    <DataTemplate x:Key="DimensionsTemplate" >
        <TextBlock Text="{Binding}"
                       Padding="5"
                       VerticalAlignment="Center"
                       FontSize="32"/>
    </DataTemplate>
</Window.Resources>

我正在尝试实现在ItemsControl中拖放项目的能力(即能够重新排序整数)。有没有人有一个简单的例子来说明如何做到这一点?我连接了PreviewMouseMove、DragEnter和Drop事件。问题是,我无法确定如何确定要拖动的项目以及它被拖到哪里。整个ItemsControl似乎被传递到事件中。

EN

回答 1

Stack Overflow用户

发布于 2016-05-12 18:47:52

下面是我如何做到这一点的一个例子。

XAML:

代码语言:javascript
复制
<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:

代码语言:javascript
复制
 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()); }
    }
}

事件:

代码语言:javascript
复制
 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);
        }           
    }

上面的例子有点复杂,因为list的每一项都是Button,而在Button click上,我也必须执行一些操作。你的案子相对容易。

对于许多开发人员来说,

拖放可能会令人困惑。但以下是如何做到这一点的要点:

  1. 使用PreviewMouseMove事件实际启动拖动,在处理程序中使用DragDrop.DoDragDrop事件引发与DragDrop相关的事件和Cursorssender参数是当前捕获鼠标的元素(在本例中是正在拖动的UIElement )。如果
  2. 希望更改Mouse当前拖动的元素的可视化,则使用DragEnter & DragOver事件。situation.
  3. Use参数是当前拖到/刚刚结束拖到sender Drop事件以处理已删除元素的元素。happened.
  4. Use参数是在这些事件之间传递信息的Drop sender DataObject对象的元素。类的SetData方法用于在其中添加数据。这个方法有两个参数,它们的工作方式类似于key-value对。设置之后,您可以通过传递DragDrop作为参数的GetData方法,在下一个被调用的key事件中获取数据。(即e.Data.GetData("Source"))

)

Here是一个相对的帖子。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3534958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档