-2

I have a generic ViewModel:

ViewModel

public class GenericViewModel<T>
{
    public IList<T> SomeList {get; set;}
}

I have to bind the MainWindow's DataContext to this GenericViewModel. However, I do not know how I should put the thing for <T>:

MainWindow's Code Behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new GenericViewModel<????>(); // What should I put
    }
}

The reason I would like to make the ViewModel generic is, I want the List inside it to accept any class's object passed to it, and I have made several dummy class to test it:

DummyModel1

public class DummyModel1
{
    public string Name { get; set; }
    public string ID { get; set; }
}

DummyModel2

public class DummyModel2
{
    public string Name { get; set; }
    public string ID { get; set; }
    public string Sex { get; set; }
    public string Email { get; set; }
}

So, how should I do?

In addition, is there any way to make the application know what the object class passed in before initialize the application?

Roxana Sh
  • 294
  • 1
  • 3
  • 14
Tom Fong
  • 125
  • 8

2 Answers2

0

In order to have instances of multiple types in a single list, you don't need a generic view model. All you need is this:

public class ViewModel
{
    public ObservableCollection<object> SomeList { get; } =
        new ObservableCollection<object>();
}

Assign it to the MainWindow's DataContext and add any type of object:

public MainWindow()
{
    InitializeComponent();

    var vm = new ViewModel();
    DataContext = vm;

    vm.SomeList.Add(new DummyModel1 { Name = "?", ID = 1 });
    vm.SomeList.Add(new DummyModel2 { Name = "?", ID = 2, ... });
}

In XAML make sure you have different DataTemplate for the different types like

<Window.Resources>
    <DataTemplate DataType="{x:Type local:DummyModel1}">
        ...
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:DummyModel2}">
        ...
    </DataTemplate>
</Window.Resources>

Then an ItemsControl (or a derived element like a ListBox) would automatically use the appropriate DataTemplate for the elements in its ItemsSource collection:

<ItemsControl ItemsSource="{Binding SomeList}"/> 
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • If I don't use Generic and use object instead of T, it states that "Cannot convert from DummyModel to object. – Tom Fong Aug 26 '19 at 05:53
0

You could create a DummyModel base class that DummyModel2 and any other specialized class inherits from:

public class DummyModel
{
    public string Name { get; set; }
    public string ID { get; set; }
}

public class DummyModel2 : DummyModel
{
    public string Sex { get; set; }
    public string Email { get; set; }
}

...and use an IList<DummyModel> property to which you can add any type of DummyModel:

public class GenericViewModel
{
    public IList<DummyModel> SomeList {get; set;}
}

If you want to be able to objects of any type to the collection, it makes no sense to use either generics or a strongly-typed IList.

mm8
  • 163,881
  • 10
  • 57
  • 88