Xamarin.Forms 中附加属性的绑定问题

Posted

技术标签:

【中文标题】Xamarin.Forms 中附加属性的绑定问题【英文标题】:Issue with bindings on attached properties in Xamarin.Forms 【发布时间】:2017-07-07 09:07:52 【问题描述】:

编辑:请不要发布有关如何在 Xamarin.Forms 中实现手势的答案 - 请先阅读整篇文章。

我正在使用附加属性创建滑动手势处理程序作为效果(如Xamarin guides 中所述)。跳过方法讨论我有一个关于附加属性实现的奇怪问题。

长话短说(代码如下)- XAML 绑定到附加属性不起作用。我的静态类中的Set\Get...Command 方法根本没有执行。我没有看到任何 Debug.WriteLine() 导致应用程序输出。调试器也没有命中在那里设置的断点。与...CommandPropertyChanged() 处理程序相同。

这是我的属性处理类:

namespace Core.Effects

    public static class Gesture
    
        public static readonly BindableProperty SwipeLeftCommandProperty =
            BindableProperty.CreateAttached("SwipeLeftCommand", typeof(ICommand), typeof(Gesture), null, propertyChanged: SwipeLeftCommandPropertyChanged);

        public static readonly BindableProperty SwipeRightCommandProperty =
            BindableProperty.CreateAttached("SwipeRightCommand", typeof(ICommand), typeof(Gesture), null, propertyChanged: SwipeRightCommandPropertyChanged);

        public static ICommand GetSwipeLeftCommand(BindableObject view)
        
            Debug.WriteLine("GetSwipeLeftCommand");
            return (ICommand) view.GetValue(SwipeLeftCommandProperty);
        

        public static void SetSwipeLeftCommand(BindableObject view, ICommand value)
        
            Debug.WriteLine("SetSwipeLeftCommand");
            view.SetValue(SwipeLeftCommandProperty, value);
        

        public static ICommand GetSwipeRightCommand(BindableObject view)
        
            Debug.WriteLine("GetSwipeRightCommand");
            return (ICommand) view.GetValue(SwipeRightCommandProperty);
        

        public static void SetSwipeRightCommand(BindableObject view, ICommand value)
        
            Debug.WriteLine("SetSwipeRightCommand");
            view.SetValue(SwipeRightCommandProperty, value);
        

        private static void SwipeLeftCommandPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        
            Debug.WriteLine("SwipeLeftCommandPropertyChanged");
            // ...
        

        private static void SwipeRightCommandPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        
            Debug.WriteLine("SwipeRightCommandPropertyChanged");
            // ...
        

        // ...
    

这是我在 XAML 中使用它的方式:

<?xml version="1.0" encoding="UTF-8"?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:effects="clr-namespace:Core.Effects"
             x:Class="Core.Pages.RequestDetailsPage">
    <ContentPage.Content>
        <StackLayout Spacing="0"
                     Padding="0"
                     VerticalOptions="FillAndExpand"
                     effects:Gesture.SwipeLeftCommand="Binding NavigateToPreviousRequestCommand"
                     effects:Gesture.SwipeRightCommand="Binding NavigateToNextRequestCommand">

我的视图模型中有相应的命令(用 FreshMvvm 框架实现的 MVVM):

namespace Core.PageModels

    public class RequestDetailsPageModel : FreshBasePageModel
    
        public IRelayCommand NavigateToNextRequestCommand;
        public IRelayCommand NavigateToPreviousRequestCommand;

IRelayCommand 是我从ICommand 派生的类型。 BindingContext 由 FreshMvvm 正确设置(在此视图的其他地方运行良好)。

有什么线索吗?

【问题讨论】:

【参考方案1】:

我已经在 GitHub 上完成了示例 repo,请查看下面的链接。

https://github.com/softlion/XamarinFormsGesture

https://github.com/tkowalczyk/SimpleCustomGestureFrame

http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/

【讨论】:

感谢您的回答,但我的问题不是如何实现滑动手势(我已经看到了这些解决方案,它们帮助我实现了其他部分)但是 为什么附加属性不是工作关于第一个回购 - 由于still opened issue,它不起作用 你在创建渲染器吗? 不,我不知道。请再次仔细阅读整个问题(和我的评论) 试试这个 public RelayCommand NavigateToNextRequestCommand get;放; with NavigateToNextRequestCommand = new RelayCommand(NavigateToNextRequestCommand); 命令已在视图模型构造函数中初始化(为简洁起见未显示)【参考方案2】:

我的错误很简单(也很难追踪)。绑定不作用于字段,而是作用于属性:

namespace Core.PageModels

    public class RequestDetailsPageModel : FreshBasePageModel
    
        public IRelayCommand NavigateToNextRequestCommand get; set;
        public IRelayCommand NavigateToPreviousRequestCommand get; set;

【讨论】:

以上是关于Xamarin.Forms 中附加属性的绑定问题的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin Forms 将属性绑定到标签的文本

将绑定值设置为 Xamarin Forms 中行为的参数

Xamarin.Forms 可绑定属性

Xamarin Forms 可绑定属性与普通属性

Xamarin.Forms 自定义 TapGestureRecognizer 附加属性

Xamarin.Forms Tapped 事件,没有可绑定的属性