【问题标题】:Xamarin Forms Custom View, Bindable Observable Collection<object> throws "Specific Cast Not Valid"Xamarin 窗体自定义视图,可绑定 Observable Collection<object> 抛出“特定转换无效”
【发布时间】:2020-06-18 11:35:43
【问题描述】:

我正在使用一组可绑定属性(包括我自己的模型的可绑定可观察集合类型)在 xamarin 表单中创建自定义视图。这些可观察的集合用作自定义视图的数据源并实时更新。在添加不同类型的模型并开始代码重构之前,一切都很好。

自定义视图支持的模型集很少,并且任何时候都只能有一个可观察到的任何模型类型的集合。最初,我为每种类型使用不同的属性进行管理,然后为了使其更通用,我尝试使用单个属性来处理它。那是我更换的时候

在 CustomView.cs 中

ObservableCollection<ModelA> ADataSource ObservableCollection<ModelB> BDataSource

ObservableCollection&lt;object&gt; DataSource

在 ViewModel 我有

ObservableCollection&lt;ModelA&gt; AList

现在,当应用程序运行时,自定义视图会为通用可观察集合抛出错误“特定转换无效”。在 Property_Changing 事件处理程序中调试时,我可以通过快速监视将 newValue 强制转换为 Observable Collection。

如何处理这个问题并使通用的 observable 集合属性支持多类型模型。

提前致谢

【问题讨论】:

标签: generics xamarin.forms observablecollection custom-view bindableproperty


【解决方案1】:

如果你想在 ContentView 中使用 ObservableCollection modelbs 可绑定属性,那么在 ContentPage 中使用这个自定义控件,我做了一个示例,你可以看看:

内容视图:

<ContentView
x:Class="demo3.contentview.View2"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="customlistview"
mc:Ignorable="d">
<ContentView.Content>
    <StackLayout>
        <ListView x:Name="listview1" ItemsSource="{Binding Items, Source={x:Reference customlistview}}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label Text="{Binding name}" />
                            <Label Text="{Binding age}" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentView.Content>

 public partial class View2 : ContentView
{
    public static  BindableProperty ItemsProperty = BindableProperty.Create("ItemsSource", typeof(ObservableCollection<object>), typeof(View2),null,BindingMode.TwoWay,propertyChanged: (bindable, oldValue, newValue) => OnItemsSourceChanged(bindable, oldValue, newValue));

    private static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control =(View2)bindable;
        control.listview1.ItemsSource =(ObservableCollection<object>) newValue;
    }
    /// <summary>
    /// Accessors
    /// </summary>
    public ObservableCollection<object> Items
    {
        get { return (ObservableCollection<object>)GetValue(ItemsProperty); }
        set
        {
            SetValue(ItemsProperty, value);
        }
    }
    public View2()
    {
        InitializeComponent();

    }
}

内容页面:

 <ContentPage.Content>
    <StackLayout>
        <local:View2 Items="{Binding modelas}" />

    </StackLayout>
</ContentPage.Content>

public partial class Page26 : ContentPage
{
    public ObservableCollection<object> modelas {get;set;}
    public ObservableCollection<object> modelbs { get; set; }
    public Page26()
    {
        InitializeComponent();
        modelas = new ObservableCollection<object>()
        {
            new modela(){name="cherry",age=12},
            new modela(){name="barry",age=20}
        };

        modelbs = new ObservableCollection<object>()
        {
            new modelb(){firstname="aaa",age=12},
            new modelb(){firstname="bbb",age=27}
        };
        this.BindingContext = this;

    }
}

public class modela
{
    public string name { get; set; }
    public int age { get; set; }
}

public class modelb
{
    public string firstname { get; set; }
    public int age { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2017-10-05
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多