Как динамически связать ItemSource объекта ListView, который имеет ItemTemplateSelector, содержащий несколько DataTemplates, которые имеют разные типы данных? - PullRequest
3 голосов
/ 05 ноября 2019

У меня есть ItemTemplateSelector, который содержит несколько DataTemplates, которые имеют разные типы данных. Таким образом, у меня есть несколько ItemSources на основе выбранного модуля. Как связать мой ListView с несколькими ItemSources на основе выбранного модуля?

Объяснение:

1) ViewModel_A - это мой ItemSource, а DataTemplateA - мой DataTemplate, когда мой модуль AВыбранный

2) ViewModel_B - это мой ItemSource. DataTemplateB - мой DataTemplate, когда выбран мой модуль B

Я попытался реализовать BaseViewModel и попытался связать тип BaseViewModel в моем ItemSource, но это не позволяетдоступ к свойствам производного класса.

Как динамически выбирать My ItemSource?

1 Ответ

1 голос
/ 05 ноября 2019

Шаг 1

Сначала создайте UserControl, который содержит ваш ListView в вашем Xaml и два DependancyProperty для ItemSource и DataTemplate

DataList. Xaml

<UserControl
x:Class="MultipleDataTemplate.DataList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>

   <Grid>
   <ListView ItemsSource="{x:Bind ItemsSource,Mode=OneWay}"></ListView>
   </Grid>
</UserControl>

DataList.xaml.cs

public sealed partial class DataList : UserControl
{
    public DataList()
    {
        this.InitializeComponent();
    }
    #region ItemsSource
    public object ItemsSource
    {
        get { return (object)GetValue(ItemsSourceProperty); }
        set {  SetValue(ItemsSourceProperty, value); }
    }              
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(DataList), new PropertyMetadata(null));
    #endregion
    #region ItemTemplate
    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(nameof(ItemTemplate), typeof(DataTemplate), typeof(DataList), new PropertyMetadata(null));
    #endregion
}

Шаг 2

Теперь вы можете управлять этим пользователем с помощью несколькихDataTemplate и несколько элементов источника, как показано ниже

MainPage.xaml

<Page
    x:Class="MultipleDataTemplate.Cars"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:controls="using:MultipleDataTemplate">
    <Page.Resources>
        <DataTemplate x:Key="CarKey" x:DataType="controls:Car">
            <Grid>
                <TextBlock Text="{x:Bind carprop1}"></TextBlock>
                <TextBlock Text="{x:Bind carprop2}"></TextBlock>

            </Grid>
        </DataTemplate>
        <DataTemplate x:Key="BikeKey" x:DataType="controls:Bike">
            <Grid>
                <TextBlock Text="{x:Bind Bikeprop1}"></TextBlock>
                <TextBlock Text="{x:Bind Bikeprop2}"></TextBlock>

            </Grid>
        </DataTemplate>
    </Page.Resources>
    <Grid>        
        <controls:DataList ItemsSource="{x:Bind ItemSource,Mode=OneWay}" ItemTemplate="{x:Bind ItemTemplate}"></controls:DataList>
        <StackPanel>
            <Button Content="Cars" Click="CarsClick"/>
            <Button Content="Bike" Click="BikeClick"/>
        </StackPanel>
    </Grid>
</Page>

MainPage.xaml.cs

public sealed partial class Cars : Page, INotifyPropertyChanged
{
    public object _ItemSource { get; set; }

    public object ItemSource
    {
        get { return _ItemSource; }
        set
        {
            _ItemSource = value;
            this.OnPropertyChanged();
        }
    }
    public DataTemplate _itemTemplate { get; set; }

    public DataTemplate ItemTemplate
    {
        get { return _itemTemplate; }
        set
        {
            _itemTemplate = value;
            this.OnPropertyChanged();
        }
    }
    public Cars()
    {
        this.InitializeComponent();
    }
    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;


    private void CarsClick(object sender, RoutedEventArgs e)
    {
        ItemSource = new List<Car>() { new Car() { carprop1 = "1", carprop2 = "2" } };
        ItemTemplate = this.Resources["CarKey"] as DataTemplate;
    }

    private void BikeClick(object sender, RoutedEventArgs e)
    {
        ItemSource = new List<Bike>() { new Bike() { Bikeprop1 = "1", Bikeprop2 = "2" } };
        ItemTemplate = this.Resources["BikeKey"] as DataTemplate;
    }
}
public class Car
{
    public string carprop1 { get; set; }
    public string carprop2 { get; set; }
}
public class Bike
{
    public string Bikeprop1 { get; set; }
    public string Bikeprop2 { get; set; }
}
...