1


I have defined a type Board which containes a public property

ObservableCollection<Column> Columns

I would like to display it with use of MVVM pattern. I created BoardView and bound it to BoardViewModel. BoardViewModel exposes public property Board of type Board. BoardView contains a control ItemsControl which sets ItemsSource={Binding Board.Columns}.

<ItemsControl ItemsSource="{Binding Board.Columns}">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Border BorderThickness="2" Margin="10" BorderBrush="#9f9f9f" Width="250">
            <v:BoardColumnView Background="#e3e3e3" />
        </Border>
    </DataTemplate>
</ItemsControl.ItemTemplate>

BoardColumnView should show properties of Column type and this works good. My problem is that I want to create a ViewModel for BoardColumn, and instead of showing only properties of Column type I want to show BoardColumnViewModel which would have defined inside a Column property. How can I achieve that? thanks in advance!

Jarek
  • 166
  • 1
  • 13
  • 1
    Very unclear. Why cannot you just define BoardColumnViewModel inside of Column class as you wrote at the end of your question? – keymusicman Jul 20 '15 at 21:49
  • Hi, sorry for unclear description, but I did my best. I cannot use Column to hold ColumnBoardViewModel, since it is database entity. I just wonder If I can bind BoardColumnView.xaml.DataContext to BoardColumnViewModel and in ItemsControl just bind BoardColumnViewModel.Column to ItemsControl.CurrentItem. – Jarek Jul 20 '15 at 22:29
  • 1
    Perhaps it could help: http://stackoverflow.com/questions/1939907/binding-to-currentitem-in-a-itemscontrol – keymusicman Jul 20 '15 at 22:38
  • Hi, it helped and led me to few interesting threads on Stackoverflow. thanks – Jarek Jul 22 '15 at 09:52

2 Answers2

1

In my understanding is BoardColumnView an own UserControl?

If so just set the DataContext of this UserControl with this.DataContext = new BoardColumnViewModel(); in code behind or use XAML equivalent. Then create in your BoardViewModel an ObserveableCollection<> which holds multiple Instances of BoardColumnView and set the ItemSource to this collection. In your BoardColumnView XAML define your Layout, Bindings, etc. which are displayed in BoardView.

So every time you add a BoardColumnView to the ItemsSource, which is bound to the collection, a new instance of BoardColumnViewModel is getting created.

...That is my understanding of your Problem, but I might be completely wrong :).

  • Hi, thank you for your answer. Do I understand your answer correctly, you wrote that in body of BoardViewModel I should have a collection of BoardColumnView (or do you meant BoardColumnViewModel)? Because, having the connection to BoardColumnView in ViewModel violates the whole idea of MVVM. If this is just an error then I think it's very good solution. thank you a lot. – Jarek Jul 22 '15 at 10:06
  • Yeah little mistake on my side. Pavlos answer is the way to go! – Sebastian Richter Jul 22 '15 at 13:54
1

You could simply define a Columns property in your BoardViewModel that would contain a collection of BoardColumnViewModel. Something like this:

public ObservableCollection<BoardColumnViewModel> Columns { get; private set; }

You will need to initialize this property somewhere in BoardViewModel, for example:

public BoardViewModel(...)
{
     ...
     Columns = new ObservableCollection<BoardColumnViewModel>(Board.Columns.Select(c => new BoardColumnViewModel(c)));
}

And then bind to that property, instead of Board.Columns:

<ItemsControl ItemsSource="{Binding Columns}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderThickness="2" Margin="10" BorderBrush="#9f9f9f" Width="250">
                <v:BoardColumnView Background="#e3e3e3" />
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

As a general principle in MVVM is that it is not recommended to bind directly to a model. Instead you should always try to bind to a view model. This is why you have the problem you've described - because you bind to a public property Board, which is your model.

Pavlo Glazkov
  • 20,498
  • 3
  • 58
  • 71
  • Hi, I thought about such solution, but I had concerns whether it's good or bad solution. You convinced me that this is the way to go. Thanks that you mentioned that binding to Model directly is not recommended, I was not aware of this. thank you so much! – Jarek Jul 22 '15 at 10:15