Пользовательский вид форм Xamarin, привязываемая наблюдаемая коллекция <object>бросков "Specifi c Cast Not Valid" - PullRequest
0 голосов
/ 05 марта 2020

Я создаю собственное представление в xamarin Forms с набором свойств Bindable, включая тип наблюдаемых коллекций Bindable моих собственных моделей. Эти наблюдаемые коллекции служат источником данных для пользовательского представления и обновляются в режиме реального времени. Все было хорошо, пока не добавили разные типы моделей и не начался рефакторинг кода.

Существует несколько наборов моделей, которые поддерживает пользовательское представление, и в любой момент времени может быть только одна наблюдаемая коллекция типов для любой модели. Изначально мне удавалось использовать разные свойства для каждого типа, затем, чтобы сделать его более обобщенным c, я попытался обработать его с помощью одного свойства. Именно тогда я заменил

в CustomView.cs

ObservableCollection<ModelA> ADataSource ObservableCollection<ModelB> BDataSource

на

ObservableCollection<object> DataSource

В ViewModel у меня есть

ObservableCollection<ModelA> AList

Теперь при запуске приложения пользовательское представление выдает ошибку «Specifi c Преобразование недопустимо» для наблюдаемой коллекции generi c. Во время отладки в обработчике событий Property_Changing я могу преобразовать newValue с помощью функции быстрого просмотра в Observable Collection.

Как с этим справиться и заставить универсальное c наблюдаемое свойство коллекции поддерживать модели нескольких типов.

Заранее спасибо

1 Ответ

0 голосов
/ 06 марта 2020

Если вы хотите использовать свойство привязки ObservableCollection modelbs в ContentView, а затем использовать этот пользовательский элемент управления в ContentPage, я сделаю один пример, который вы можете посмотреть:

ContentView:

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

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