XF自定义选择器ItemsSource属性绑定不起作用

时间:2019-08-14 22:02:01

标签: xamarin xamarin.forms xamarin.android

我正在尝试创建带有标签和选择器的自定义控件(将来我计划添加不引人注目的验证)。下面是控件的xaml。

=ARRAYFORMULA(QUERY(TRIM(TRANSPOSE(SPLIT(TEXTJOIN(", ", 1, C2:C), ","))), 
 "select Col1,count(Col1) group by Col1 label count(Col1)''", 0))

下面是具有可绑定属性的代码:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             x:Class="XFTestBench.ExtendedPicker">
    <ContentView.Content>
        <StackLayout>
            <Label x:Name="LblText" Text="{Binding LabelText}" />
            <Picker x:Name="Pkr" ItemsSource="{Binding Source}"/>
        </StackLayout>
    </ContentView.Content>
</ContentView>

[XamlCompilation(XamlCompilationOptions.Compile)] public partial class ExtendedPicker : ContentView { BindableProperty LabelTextProperty = BindableProperty.Create("LabelText", typeof(string), typeof(ExtendedPicker), null, BindingMode.TwoWay, propertyChanged: OnLabelTextChanged); public string LabelText { get { return GetValue(LabelTextProperty).ToString(); } set { SetValue(LabelTextProperty, value); } } private static void OnLabelTextChanged(BindableObject bindable, object oldValue, object newValue) { ((ExtendedPicker)bindable).LblText.Text = newValue?.ToString() ?? ""; } BindableProperty SourceProperty = BindableProperty.Create("Source", typeof(IList), typeof(ExtendedPicker), default(IList), BindingMode.TwoWay, propertyChanged: OnSourceChanged); public IList Source { get { return (IList)GetValue(SourceProperty); } set { SetValue(SourceProperty, value); } } private static void OnSourceChanged(BindableObject bindable, object oldValue, object newValue) { ((ExtendedPicker)bindable).Pkr.ItemsSource = (IList)newValue; } public ExtendedPicker() { InitializeComponent(); } } 标签正确绑定。但是,我无法绑定LabelText属性。这是控件的用法。

Source

这是数据源。通过在选择器中使用数据源,我已经验证了数据源是正确的。

<extensions:ExtendedPicker LabelText="AHOY THERE" Source="{Binding Cats}"/>

我已经查看了Visual Studio输出窗口,但未记录任何内容。没有例外。我在getter,setter上设置了断点;但只有吸气剂被击中。 public IList<string> Cats { get; set; } Cats = new List<string> { "Black Cats", "White Cats", "Red Cats", "Brown Cats" }; 也未命中。绑定OnSourceChanged时,UI中没有任何显示。如果将其取出,则会显示控件。

2 个答案:

答案 0 :(得分:0)

首先,您不必创建propertyChanged委托,只需将Xaml中的属性正确绑定到代码隐藏中的自定义绑定属性即可。

第二,您没有正确绑定这些属性。

Xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             x:Class="XFTestBench.ExtendedPicker"
             x:Name="RootLayout">
    <ContentView.Content>
        <StackLayout>
            <Label x:Name="LblText" 
                   Text="{Binding Source={x:Reference RootLayout}, Path=LabelText}" />
            <Picker x:Name="Pkr" 
                   ItemsSource="{Binding Source={x:Reference RootLayout}, Path=Source}"/>
        </StackLayout>
    </ContentView.Content>
</ContentView>

隐藏代码

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ExtendedPicker : ContentView
{
    BindableProperty LabelTextProperty =
        BindableProperty.Create("LabelText", typeof(string), typeof(ExtendedPicker), null, BindingMode.TwoWay);

    public string LabelText
    {
        get { return GetValue(LabelTextProperty).ToString(); }
        set { SetValue(LabelTextProperty, value); }
    }


    BindableProperty SourceProperty = 
        BindableProperty.Create("Source", typeof(IList), typeof(ExtendedPicker), default(List), BindingMode.TwoWay);

    public IList Source
    {
        get { return (IList)GetValue(SourceProperty); }
        set { SetValue(SourceProperty, value); }
    }

    public ExtendedPicker()
    {
        InitializeComponent();
    }
}

答案 1 :(得分:0)

最后想到了这一点。这有两个问题。

首先,BindableProperty必须为public static readonly,这是我在创建此示例时忘记的约定。

其次,更重要的是,我错误地设置了BindingContext。我通过对xaml进行以下更改来修复它:

<extensions:ExtendedPicker BindingContext="{x:Binding M}" LabelText="{Binding Label}" Src="{Binding Cats}" />

以及下面的视图模型:

public class Model
    {
        public string Label { get; set; }

        public IList<string> Cats { get; set; }
    }

private Model _m;
public Model M { get => _m; set => SetProperty(ref _m, value); }

有了这些更改,我的ExtendedPicker拥有了可以绑定到LabelCats的正确上下文