拖放在MVVM与ScatterView(Drag and Drop in MVVM with Sca

2019-07-29 03:57发布

我试图实现拖放在使用MVVM模式构建的表面应用拖放功能。 我竭力要拿出一个办法来实现这一点的同时秉承MVVM模式。 虽然我试图曲面应用程序中做到这一点,我认为解决的办法是足够一般适用于WPF为好。

我想产生了以下功能:

  • 用户接触ScatterViewItem内的FrameworkElement的开始的拖动操作(ScatterViewItem的特定部分启动拖/放功能)
  • 当拖动操作开始时被创建并在原ScatterViewItem实行的是ScatterViewItem的副本,副本是什么样的用户会拖,并最终下降
  • 用户可将商品拖放到另一个ScatterViewItem(置于单独ScatterView)

总体相互作用是非常类似于在表面SDK中提供的应用程序的购物,不同之处在于源对象均包含一个ScatterView而非列表框之内。

我不能确定如何才能使为了提供这种功能我的ViewModels之间正常的通信进行。 我所遇到的主要问题是复制ScatterViewItem当用户接触FrameworkElement的。

Answer 1:

你可以使用一个附加属性。 创建附加属性和在setProperty方法结合到DROP掉事件:


public static void SetDropCommand(ListView source, ICommand command)
        {
            source.Drop += (sender, args) =>
                               {
                                   var data = args.Data.GetData("FileDrop");
                                   command.Execute(data);
                               };
        }

然后你就可以在你的视图模型绑定命令在视图中的相关控制。 很显然,你可能想使你的附加属性适用于特定类型的控制,而不是一个列表视图。

希望帮助。



Answer 2:

我在得到史蒂夫帕萨提斯的思想工作一展身手。 过了好一会儿 - 自定义依赖属性是很容易出错。 在我看来就像SetXXX是错误的地方,把你的副作用- WPF不必去虽然有,就可以直接去DependencyObject.SetValue ,但PropertyChangedCallback将始终被调用。

所以,这里的完整和工作自定义附加属性的代码:

using System.Windows;
using System.Windows.Input;

namespace WpfApplication1
{
    public static class PropertyHelper
    {
        public static readonly DependencyProperty DropCommandProperty = DependencyProperty.RegisterAttached(
            "DropCommand",
            typeof(ICommand),
            typeof(PropertyHelper),
            new PropertyMetadata(null, OnDropCommandChange));

        public static void SetDropCommand(DependencyObject source, ICommand value)
        {
            source.SetValue(DropCommandProperty, value);
        }

        public static ICommand GetDropCommand(DependencyObject source)
        {
            return (ICommand)source.GetValue(DropCommandProperty);
        }

        private static void OnDropCommandChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ICommand command = e.NewValue as ICommand;
            UIElement uiElement = d as UIElement;
            if (command != null && uiElement != null)
            {
                uiElement.Drop += (sender, args) => command.Execute(args.Data);
            }

            // todo: if e.OldValue is not null, detatch the handler that references it
        }
    }
}

在要使用此XAML标记,你可以做如

xmlns:local="clr-namespace:WpfApplication1"
...
<Button Content="Drop here" Padding="12" AllowDrop="True"
   local:PropertyHelper.DropCommand="{Binding DropCommand}" />

。而剩下的只是确保你的视图模型,绑定和命令是正确的。

此版本传递一个IDataObject通过,其似乎更给我的命令-你可以查询它在命令文件或什么的。 但是,这只是当前的偏好,答案不是一个基本特征。



文章来源: Drag and Drop in MVVM with ScatterView