簡體   English   中英

BindableProperty:類型不匹配

[英]BindableProperty: Type Mismatch

我想擴展 Xamarin.Forms Picker,以便我可以將集合綁定到它。 快速搜索后,我找到了這個頁面: Picker Example有兩個很好的例子。 拒絕只是復制和粘貼代碼(出於學習目的),我繼續根據這兩個示例編寫自己的代碼。

除了我的不起作用外,它幾乎相同。

當我不向 ItemsSource 提供集合時,一切正常。 每當我分配一個集合時,我都會收到以下錯誤:

Xamarin.Forms.Xaml.XamlParseException:位置 9:32。 無法分配屬性“ItemsSource”:“Xamarin.Forms.Binding”和“System.Collections.IEnumerable”之間的類型不匹配

選擇器:

public class BindablePicker : Picker
{
    private static readonly BindableProperty ItemsSourceProperty =
        BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(BindablePicker), null, propertyChanged: OnItemsSourceChanged);

    private static readonly BindableProperty SelectedItemProperty =
        BindableProperty.Create("SelectedItem", typeof(object), typeof(BindablePicker));

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }
    public object SelectedItem
    {
        get { return GetValue(SelectedItemProperty); }
        set { SetValue(SelectedItemProperty, value); }
    }
    public string DisplayMember { get; set; }


    private static void OnItemsSourceChanged(BindableObject bindable, Object oldValue, Object newValue)
    {
        var newval = newValue as IEnumerable; //Had to implement this because of the non-generic .Create() method expects Object as param.
        var picker = bindable as BindablePicker;

        if (picker != null)
        {
            picker.Items.Clear();
            if (newval == null) return;

            foreach (var item in newval)
            {
                if (string.IsNullOrEmpty(picker.DisplayMember))
                {
                    picker.Items.Add(item.ToString());
                }
                else
                {
                    var prop = item.GetType()
                        .GetRuntimeProperties()
                        .FirstOrDefault(p => string.Equals(p.Name, picker.DisplayMember, StringComparison.OrdinalIgnoreCase));

                    picker.Items.Add(prop.GetValue(item).ToString());
                }
            }
        }
    }

    private void OnSelectedIndexChanged(object sender, EventArgs args)
    {
        if (SelectedIndex < 0 || SelectedIndex > Items.Count - 1)
        {
            SelectedItem = null;
        }
        else
        {
            SelectedItem = ItemsSource.ItemOf(SelectedIndex); //ItemOf is an extension method I made for IEnumerable (has to be tested).
        }
    }
}

視圖模型(部分):

public class HomePageViewModel : ViewModelBase
{
    //In the app this is populated with a List<Person>.
    public IEnumerable<Person> People { get; set; }
}

XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:controls="clr-namespace:TestApp.Controls;assembly=TestApp"
         x:Class="TestApp.Views.HomePage">
  <ContentPage.Content>
     <StackLayout>

         <controls:BindablePicker ItemsSource="{Binding People}"
                                  HorizontalOptions="Center" />
     </StackLayout>
  </ContentPage.Content>
</ContentPage>

請注意,鏈接頁面中的第一個示例選擇器適用於提供的 VM/視圖設置。

我還沒有完成選擇器,我仍然想提供對 SelectedItem 屬性的 TwoWay 綁定和對 ObservableCollection 的支持。

你的,

一開始我以為我要瘋了。

然后我覺得有什么東西嚴重壞了。

但最后我想通了...

private static readonly BindableProperty ItemsSourceProperty =
    BindableProperty.Create("ItemsSource", typeof(IEnumerable),  
    typeof(BindablePicker), null, propertyChanged: OnItemsSourceChanged);

為了讓 Xaml 解析器看到BindableProperty本身,它必須是public (和static ,但你做對了那部分)。

在您的情況下,Xaml 解析器看不到BindableProperty ,因此它回退到該屬性,但它無法設置Binding ,並且由於類型不匹配,您會收到異常。

將您的代碼更改為

public static readonly BindableProperty ItemsSourceProperty =
    BindableProperty.Create("ItemsSource", typeof(IEnumerable),  
    typeof(BindablePicker), null, propertyChanged: OnItemsSourceChanged);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM