我正在尝试创建带有标签和选择器的自定义控件(将来我计划添加不引人注目的验证)。下面是控件的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中没有任何显示。如果将其取出,则会显示控件。
答案 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
拥有了可以绑定到Label
和Cats
的正确上下文