【问题标题】:Xamarin.Forms binding to a binding property or somethingXamarin.Forms 绑定到绑定属性或其他东西
【发布时间】:2018-08-27 16:31:29
【问题描述】:

我有一个页面

<?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:controls="clr-namespace:PassSystem.Controls;assembly=PassSystem"
             x:Class="PassSystem.Views.CreatePassPage"
             Title="Оформление пропуска">
    <ScrollView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <StackLayout>
            <FlexLayout Direction="Column" BackgroundColor="White">
                <controls:ActionOption Title="Название" Value="1" LeftMargin="18">
                </controls:ActionOption>
            </FlexLayout>
        </StackLayout>
    </ScrollView>
</ContentPage>

我有内容视图

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:PassSystem.Controls;assembly=PassSystem"
             xmlns:effects="clr-namespace:PassSystem.Effects;assembly=PassSystem"
             xmlns:local="clr-namespace:PassSystem"
             x:Class="PassSystem.Controls.ActionOption">
    <FlexLayout x:Name="MainLayout" Direction="Row" JustifyContent="Center" AlignContent="Center" AlignItems="Center" HeightRequest="52"
                effects:ClickableEffect.ClickCommand="!!"
                effects:ClickableEffect.CancelCommand="{Binding UpCommand}"
                effects:ClickableEffect.UpCommand="{Binding UpCommand}"
                effects:ClickableEffect.DownCommand="{Binding DownCommand}">

        <Label Text="{Binding Title}"
               TextColor="{StaticResource PrimaryTextColor}"
               FontSize="15"
               VerticalTextAlignment="Center"
               VerticalOptions="FillAndExpand"
               FlexLayout.Grow="1"
               Margin="{Binding TitleMargin, Mode=TwoWay}">
        </Label>

        <StackLayout Orientation="Horizontal" HeightRequest="16" VerticalOptions="CenterAndExpand" Margin="0,0,8,0">
            <Label Text="{Binding Value}" FontSize="12" TextColor="{StaticResource SecondaryTextColor}" VerticalTextAlignment="Center"/>
            <controls:IconView Source="forward" HeightRequest="14" WidthRequest="14" ForegroundColor="{StaticResource AdditionalTextColor}"/>
        </StackLayout>
        <FlexLayout.Effects>
            <effects:ClickableEffect />
        </FlexLayout.Effects>
    </FlexLayout>
</ContentView>

.cs 文件

public partial class ActionOption : ContentView
    {
        public ActionOption()
        {
            InitializeComponent();
            BindingContext = this;
        }

        private string _title;
        public string Title
        {
            get => _title;
            set
            {
                if(value == _title) return;
                _title = value;
                OnPropertyChanged();
            }
        }

        private string _value;
        public string Value
        {
            get => _value;
            set
            {
                if (value == _value) return;
                _value = value;
                OnPropertyChanged();
            }
        }

        public Thickness TitleMargin => new Thickness(_leftMargin, 0, 6, 0);

        private double _leftMargin;
        public double LeftMargin
        {
            get => _leftMargin;
            set
            {
                if (Math.Abs(value - _leftMargin) < 0.01d) return;
                _leftMargin = value;
                OnPropertyChanged();
                OnPropertyChanged(nameof(TitleMargin));
            }
        }

        private ICommand _clicked;
        public ICommand Clicked
        {
            get => _clicked;
            set
            {
                if (value == _clicked) return;
                _clicked = value;
                OnPropertyChanged();
            }
        }

        public ICommand UpCommand => new Command(() => MainLayout.BackgroundColor = Color.FromHex("#fff"));
        public ICommand DownCommand => new Command(() => MainLayout.BackgroundColor = (Color)((App)Application.Current).Resources["HighlightingColor"]);
    }

我需要从页面绑定 ClickableEffect.ClickCommand。即

<controls:ActionOption Title="TitleHere" Value="1" LeftMargin="18" Clicked="{Binding ClickedCommand}">
</controls:ActionOption>

并且在控制中

`effects:ClickableEffect.ClickCommand="{Binding ClickCommand (FromPage)}"`

附加信息。可点击效果

{
        public ClickableEffect() : base("PassSystem.ClickableEffect")
        {
        }

        #region Click

        public static readonly BindableProperty ClickCommandProperty = BindableProperty
            .CreateAttached("ClickCommand", typeof(ICommand), typeof(ClickableEffect), (object)null);

        public static ICommand GetClickCommand(BindableObject view)
        {
            return (ICommand)view.GetValue(ClickCommandProperty);
        }

        public static void SetClickCommand(BindableObject view, ICommand value)
        {
            view.SetValue(ClickCommandProperty, value);
        }


        public static readonly BindableProperty ClickCommandParameterProperty = BindableProperty
            .CreateAttached("ClickCommandParameter", typeof(object), typeof(ClickableEffect), (object)null);

        public static object GetClickCommandParameter(BindableObject view)
        {
            return view.GetValue(ClickCommandParameterProperty);
        }

        public static void SetClickCommandParameter(BindableObject view, object value)
        {
            view.SetValue(ClickCommandParameterProperty, value);
        }

        #endregion
}

Android上Clickable效果的实现:

public class ClickableListener : Java.Lang.Object, View.IOnTouchListener, View.IOnClickListener, View.IOnLongClickListener
    {
        private Element Element { get; }
        private View View { get; }

        public ClickableListener(Element element, View view)
        {
            Element = element;
            View = view;
        }

        ...

        public void OnClick(View v)
        {
            Tap();
        }

        private void Tap()
        {
            var command = ClickableEffect.GetClickCommand(Element);
            var parameter = ClickableEffect.GetClickCommandParameter(Element);
            command?.Execute(parameter);
        }
    }

[assembly: ResolutionGroupName("PassSystem")]
[assembly: ExportEffect(typeof(AndroidClickableEffect), "ClickableEffect")]
namespace PassSystem.Droid.Native.Effects
{
    public class AndroidClickableEffect : PlatformEffect
    {
        private bool _attached;

        protected override void OnAttached()
        {
            //because an effect can be detached immediately after attached (happens in listview), only attach the handler one time.
            if(!_attached)
            {
                var control = Control ?? Container;

                var listener = new ClickableListener(Element, control);
                control.SetOnClickListener(listener);
                ...
                _attached = true;
            }
        }
}

如何实现?谢谢你。 附:我很难解释,希望你能理解。 :)

【问题讨论】:

    标签: xaml xamarin xamarin.forms


    【解决方案1】:

    为了实现期望的行为:

    1. ClickCommand 必须是 ClickableEffect 的附加属性。更多信息可以在官方文档中找到:Passing Effect Parameters as Attached Properties
    2. 由于您在效果和页面之间有一个ContentView,您必须确保ContentViewBindindContext 设置正确。恐怕您必须在ContentView 级别上定义ClickCommand 可绑定属性并将其绑定到效果的命令。所以:Page.BindingContext.ClickCommand => ContentView.ClickCommand => ClickableEffect.ClickCommand(其中 => 是绑定的)。

    这基本上提出了一个问题 - 为什么需要效果?

    【讨论】:

    • 1.对,我有。 2.我尝试实现它。在 ViewModel 的页面上,我创建了一个 ICommand“ClickCommand”,并且在 ContentView 中也创建了“ClickCommand”。但这对我不起作用。很可能我以某种方式错误地连接了数据。因为通过 ContentView -> СlickbleEffect 的绑定它可以工作。我需要这个效果来识别手势。
    • 2.很可能你没有将 ContentView 的 BindingContext 设置为 self。
    • 不,我写的是 BindingContext = this。
    • 不要在 ContentView 级别执行此操作,而是在使用此效果的按钮上执行此操作。
    • 可以更多吗? ContentView 本身就是我的按钮。
    猜你喜欢
    • 2014-03-14
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2021-02-02
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多