简体   繁体   English

BindableProperty:类型不匹配

[英]BindableProperty: Type Mismatch

I want to extend the Xamarin.Forms Picker so I can bind a collection to it.我想扩展 Xamarin.Forms Picker,以便我可以将集合绑定到它。 After a quick search I found this page: Picker Example with two great examples.快速搜索后,我找到了这个页面: Picker Example有两个很好的例子。 Refusing to just copy&paste the code (for learning purposes) I went on and make my own based on the two examples.拒绝只是复制和粘贴代码(出于学习目的),我继续根据这两个示例编写自己的代码。

It's almost identical except mine does not work.除了我的不起作用外,它几乎相同。

When I do not provide a collection to the ItemsSource everything works fine.当我不向 ItemsSource 提供集合时,一切正常。 Whenever I do assign a collection I get the following error:每当我分配一个集合时,我都会收到以下错误:

Xamarin.Forms.Xaml.XamlParseException: Position 9:32. Xamarin.Forms.Xaml.XamlParseException:位置 9:32。 Cannot assign property "ItemsSource": type mismatch between "Xamarin.Forms.Binding" and "System.Collections.IEnumerable"无法分配属性“ItemsSource”:“Xamarin.Forms.Binding”和“System.Collections.IEnumerable”之间的类型不匹配

Picker:选择器:

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).
        }
    }
}

ViewModel (parts):视图模型(部分):

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

XAML: 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>

Note that the first example picker from the linked page works with the provided VM/View setup.请注意,链接页面中的第一个示例选择器适用于提供的 VM/视图设置。

I'm also not finished with the picker, I still want to provide TwoWay binding to the SelectedItem property and support for ObservableCollection.我还没有完成选择器,我仍然想提供对 SelectedItem 属性的 TwoWay 绑定和对 ObservableCollection 的支持。

Yours,你的,

At first I thought I was turning mad.一开始我以为我要疯了。

Then I thought something was seriously broken.然后我觉得有什么东西严重坏了。

But finally I figured it out...但最后我想通了...

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

In order for the Xaml parser to see a BindableProperty as such, it has to be public (and static , but you got that part right).为了让 Xaml 解析器看到BindableProperty本身,它必须是public (和static ,但你做对了那部分)。

In your case, the Xaml parser doesn't see the BindableProperty , so it fallback to the property, but it doesn't have any way to set the Binding , and as the types doesn't match, you get the exception.在您的情况下,Xaml 解析器看不到BindableProperty ,因此它回退到该属性,但它无法设置Binding ,并且由于类型不匹配,您会收到异常。

Change your code to将您的代码更改为

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “未找到“SelectedDate”的属性、BindableProperty 或事件,并且“未在“DatePicker”类型中找到“SelectedDate”属性” - 'No property, BindableProperty, or event found for "SelectedDate"' and 'The Property "SelectedDate" Was not found in type "DatePicker"' 找不到“IMGSource”的属性、BindableProperty 或事件,或者值和属性之间的类型不匹配 - No property, BindableProperty, or event found for "IMGSource", or mismatching type between value and property 绑定到 BindableProperty 的数据导致错误“值和属性之间的类型不匹配” - Data binding to BindableProperty results in error "mismatching type between value and property" BindableProperty错误 - BindableProperty error 创建一个自定义 BindableProperty,它采用 XAML 中底层返回类型的自定义定义字符串表示 - Creating a custom BindableProperty that takes a custom defined string representation of the underlying return type in XAML 错误 XFC0009 未找到“LeftSetsValue”的属性、BindableProperty 或事件,或者值和属性之间的类型不匹配 - Error XFC0009 No property, BindableProperty, or event found for "LeftSetsValue", or mismatching type between value and property 有条件的类型不匹配 - Type Mismatch in conditional SqlGeography类型不匹配 - SqlGeography Type Mismatch 通用超类和类型不匹配 - Generic Superclass and type mismatch DropDownListFor报告类型不匹配 - DropDownListFor reports type mismatch
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM