WPF: Entity Framework MVVM Walk Through 2 Andy ONeills example

scott thomson 66 Reputation points
2020-10-11T01:36:01.86+00:00

I have learnt a lot from Andy O'Neill's WPF: Entity Framework MVVM Walk Through 2 example as I learn WPF and MVVM etc. Generally though I always seem to struggle on comboboxes and getting the ItemsSource, SelectedValue and SelectedValuePath set up correctly to successfully show data in the combobox. The Binding is really tricky in combination with the particular comboxbox control design. In Andys example I was trying to put a combobox inside an ItemsControl thats inside a ContentControl (Popup) thats inside a grid on a UserControl. I cannot get the data from MyObservableCollection to show in the ItemsSource. I have tried all manner of versions of comboc control construction and Binding including {Binding DataContext.MyObservableCollection, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl} , RelativeSource={RelativeSource AncestorType={x:Type local:UserControl}} and replacing UserControl with the ViewModels , and using FindAncestor etc. The DataContext is set to the ViewModel where the observable collection is and its got data in it, but seems cant get binding to work.

Any tips to look at for this type of situation would be greatly appreciated or even an answer from the great man himself Mr Andy O'Neill (anonymous userONeill) . wow imagine that

thanks
Scott

Developer technologies Windows Presentation Foundation
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2020-10-11T06:52:39.713+00:00

    Hi Scott,
    in following demo you can see how to bind ComboBoxColumn in DataGrid in UserControl.

    XAML MainWindow:

    <Window x:Class="Window064"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1.WpfApp064"  
            xmlns:uc="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"  
            mc:Ignorable="d"  
            Title="Demo ComboBox in UserControl" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Grid>  
        <uc:Window064UC1/>  
      </Grid>  
    </Window>  
    

    ViewModel as DataContext in MainWindow (and UserControl), View property for rows in DataGrid, MasterList as Lookup values for ItemsSource in DataGridComboBoxColumn, LoadDemoData for loading data (e.g. EF).

    Imports System.Collections.ObjectModel  
    Imports System.ComponentModel  
      
    Namespace WpfApp064  
      
      Public Class ViewModel  
      
        Public Sub New()  
          LoadDemoData  
        End Sub  
      
        Private cvsChild As New CollectionViewSource  
        Private colChild As New ObservableCollection(Of Data)  
        Public ReadOnly Property View As ICollectionView  
          Get  
            Return cvsChild.View  
          End Get  
        End Property  
      
        Private colMaster As New ObservableCollection(Of Master)  
        Public ReadOnly Property MasterList As ObservableCollection(Of Master)  
          Get  
            Return colMaster  
          End Get  
        End Property  
      
        Private Sub LoadDemoData()  
          Dim rnd As New Random  
          For i = 1 To 10  
            colMaster.Add(New Master With {.ID = i, .MasterInfo = $"Master {i}"})  
          Next  
          For i = 1 To 100  
            colChild.Add(New Data With {.ID = i, .Info = $"Row {i}", .FKMaster = rnd.Next(1, 11)})  
          Next  
          cvsChild.Source = colChild  
        End Sub  
      End Class  
      
      Public Class Data  
        Public Property ID As Integer  
        Public Property FKMaster As Integer  
        Public Property Info As String  
      End Class  
      
      Public Class Master  
        Public Property ID As Integer  
        Public Property MasterInfo As String  
      End Class  
      
    End Namespace  
    

    XAML UserControl (no CodeBehind)

    <UserControl x:Class="Window064UC1"  
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
                 xmlns:local="clr-namespace:WpfControlLibrary1"  
                 mc:Ignorable="d"   
                 d:DesignHeight="450" d:DesignWidth="800">  
      <Grid>  
        <Grid.Resources>  
          <CollectionViewSource x:Key="ItemsCVS" Source="{Binding MasterList}" />  
        </Grid.Resources>  
        <DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="False">  
          <DataGrid.Columns>  
            <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>  
            <DataGridTextColumn Header="Info" Binding="{Binding Info}"/>  
            <DataGridComboBoxColumn Header="Lookup"  
                                    ItemsSource="{Binding Source={StaticResource ItemsCVS}}"  
                                    DisplayMemberPath="MasterInfo"  
                                    SelectedValuePath="ID"  
                                    SelectedValueBinding="{Binding FKMaster}"/>  
          </DataGrid.Columns>  
        </DataGrid>  
      </Grid>  
    </UserControl>  
    

    Result:

    31461-x.gif

    1 person found this answer helpful.

5 additional answers

Sort by: Most helpful
  1. scott thomson 66 Reputation points
    2020-10-15T02:46:04.053+00:00

    Finally solved it. Went back and carefully looked at how it worked more closely and realised I was working with collection of row VMs as apposed to the observable collection of the class derived from the entity model so filled the combobox with a collection of these and referenced via "The Entity" reference.

    Whilst its great to use other peoples code to learn from you do have to really LEARN it as you start to modify it to suit your purpose.

    thanks gents for the help.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.