【问题标题】:Xamarin - setting a collection to custom bindable property in XAMLXamarin - 将集合设置为 XAML 中的自定义可绑定属性
【发布时间】:2017-08-16 23:30:15
【问题描述】:

我有一个自定义的ContentView,其中定义了可绑定属性:

    public IEnumerable<SomeItem> Items
    {
        get => (IEnumerable<SomeItem>)GetValue(ItemsProperty);
        set => SetValue(ItemsProperty, value);
    }

    public static readonly BindableProperty ItemsProperty = BindableProperty.Create(
        nameof(Items),
        typeof(IEnumerable<SomeItem>),
        typeof(MyControl),
        propertyChanged: (bObj, oldValue, newValue) =>
        {
        }
    );

如何在 XAML 中为此设置值?

我试过了:

<c:MyControl>
   <c:MyControl.Items>
      <x:Array Type="{x:Type c:SomeItem}">
           <c:SomeItem />
           <c:SomeItem />
           <c:SomeItem />
      </x:Array>
   </c:MyControl.Items>
</c:MyControl>

但时不时出现以下编译错误:

error : Value cannot be null.
error : Parameter name: fieldType

我做错了什么?有什么不同的方法吗?

【问题讨论】:

  • 我测试了你的代码 - 它工作正常!我认为这个编译错误是来自智能感知的误报。此外,建议您将 returnType 参数(在 Binding.Create 中)从 IEnumerable&lt;CarouselTabbedItem&gt; 更改为 IEnumerable&lt;SomeItem&gt;

标签: xaml xamarin xamarin.forms


【解决方案1】:

将您的 ContentView 更改为如下内容:

public partial class MyControl : ContentView
{
    public ObservableCollection<SomeItem> Items { get; } = new ObservableCollection<SomeItem>();

    public MyControl()
    {
        InitializeComponent();

        Items.CollectionChanged += Items_CollectionChanged;
    }

    public static readonly BindableProperty ItemsProperty = BindableProperty.Create(
        nameof(Items),
        typeof(ObservableCollection<SomeItem>),
        typeof(MyControl)
    );

    void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
       //Here do what you need to do when the collection change
    }
}

您的 IEnumerable 属性将其更改为 ObservableCollection 并订阅 CollectionChanged 事件。

还要对 BindableProperty 进行一些更改。

所以现在您可以在 XAML 中添加如下项目:

<c:MyControl>
   <c:MyControl.Items>
        <c:SomeItem />
        <c:SomeItem />
        <c:SomeItem />
        <c:SomeItem />
    </c:MyControl.Items> 
</c:MyControl>

希望这会有所帮助。-

【讨论】:

  • 好像不行。我向Items 添加了一些项目,但Items_CollectionChanged 没有被触发。
  • 不是最好的,Items_CollectionChanged 事件订阅不能在构造函数中。取而代之的是,在 BindableProperty 上使用 PropertyChanged、PropertyChanging。