MAUI:如何在代码中绑定事件属性(sender、EventArgs);绑定到 ViewModel 或代码隐藏

问题描述 投票:0回答:1

我已使用 XAML 标记成功将 DrogGestureRecognizer 的 Drop 事件绑定到 CodeBehind,如下所示:

<Label Text="MyTestItem" >
  <Label.GestureRecognizers>
    <DropGestureRecognizer AllowDrop="True" Drop="DropGestureRecognizer_Drop_Item"/>
  </Label.GestureRecognizers>
</Label>

但是,我需要在 C# 代码中完成同样的事情,因为我正在创建一个由于递归而必须动态构建的视图/控件。我的要求是从事件中获取两个参数(sender 和 DropEventArgs)。我愿意接受与 CodeBehind 或 ViewModel 一起使用的解决方案。

下面是我的尝试,但是我在多重绑定方面遇到了困难。你可以在代码中看到我的评论:

RelativeBindingSource rbs2 = new   RelativeBindingSource(RelativeBindingSourceMode.FindAncestorBindingContext, ancestorType: typeof(TreeViewPageViewModel));

DropGestureRecognizer dropgGr = new DropGestureRecognizer { AllowDrop = true };

dropgGr.Bind(DropGestureRecognizer.DropCommandProperty,
    mode: BindingMode.OneTime,
    source: rbs2,
    path: "DropGestureRecognizerDropCommand"
);

dropgGr.SetBinding(DropGestureRecognizer.DropCommandParameterProperty, new MultiBinding
{
    Bindings = new Collection<BindingBase>
    {
        new Binding("."), // Is this the sender?
        new Binding("")   // How to set the DropEvenArgs here?  x:TypeArguments="DropEventArgs"
    }
});
label.GestureRecognizers.Add(dropgGr);

已解决: 目标是允许我的控件从一个标签拖放到控件内的另一个标签,而不是外部桌面拖/放集成。我已经能够将 Flyout 菜单附加到我的标签和 TapGestureRecognizer,并使用下面的代码让它成功调用我的 ViewModel 中的命令。

            RelativeBindingSource rbs = new RelativeBindingSource(RelativeBindingSourceMode.FindAncestorBindingContext, ancestorType: typeof(ITreeViewPageViewModel));

            // Context Menu --------------------------------------
            var menuItem1 = new MenuFlyoutItem
            {
                Text = "Delete Item",
                CommandParameter = xamlItem.ItemId
            };

            menuItem1.Bind(MenuFlyoutItem.CommandProperty,
                mode: BindingMode.OneTime,
                source: rbs,
                path: "DeleteItemCommand"
            );

            var menuFlyout = new MenuFlyout();

            menuFlyout.Add(menuItem1);
            FlyoutBase.SetContextFlyout(label, menuFlyout);

            // TagGesture ----------------------------------------
            TapGestureRecognizer tgr = new TapGestureRecognizer
            {
                Buttons = ButtonsMask.Primary,
                CommandParameter = xamlItem.ItemId,
                NumberOfTapsRequired = 2
            };
            tgr.Bind(TapGestureRecognizer.CommandProperty,
                mode: BindingMode.OneTime,
                source: rbs,
                path: "ItemSelectedCommand"
                );

            label.GestureRecognizers.Add(tgr);

在上面的示例中,请注意正在设置 commandParameter,但在本例中,参数是我的数据中的 ID。 我的 DragDrop 手势真正需要的是附加到现有的 Drop“事件”而不是“命令”。事实证明这出奇的简单:

            DropGestureRecognizer dropGr = new DropGestureRecognizer { AllowDrop = true };
            dropGr.Drop += DropGr_Drop_Item; 
            label.GestureRecognizers.Add(dropGr);
        
        // This method is in the same class as the above code, and since I need to call a method in my
        // ViewModel you can see the last line that is used to accomplish this.
        private void DropGr_Drop_Item(object? sender, DropEventArgs e)
        {
            var data = e.Data.Properties["Text"].ToString();
            var sourceItemId = e.Data.Properties["ItemId"].ToString();


            var label = (sender as Element)?.Parent as Label;
            var targetItemId = label.StyleId.Substring(5);

            
            (this.BindingContext as ITreeViewPageViewModel).ReOrderItems(sourceItemId, targetItemId); 
   
        }
c# drag-and-drop event-handling maui gesture-recognition
1个回答
0
投票

我的 DragDrop 手势真正需要的是附加到现有的 Drop“事件”而不是“命令”。事实证明这出奇的简单:

    DropGestureRecognizer dropGr = new DropGestureRecognizer { AllowDrop = true };
            dropGr.Drop += DropGr_Drop_Item; 
            label.GestureRecognizers.Add(dropGr);
        
        // This method is in the same class as the above code, and since I need to call a method in my
        // ViewModel you can see the last line that is used to accomplish this.
        private void DropGr_Drop_Item(object? sender, DropEventArgs e)
        {
            var data = e.Data.Properties["Text"].ToString();
            var sourceItemId = e.Data.Properties["ItemId"].ToString();


            var label = (sender as Element)?.Parent as Label;
            var targetItemId = label.StyleId.Substring(5);

            
            (this.BindingContext as ITreeViewPageViewModel).ReOrderItems(sourceItemId, targetItemId); 
   
        }

© www.soinside.com 2019 - 2024. All rights reserved.