0

I'm attempting to learn WPF and MVVM at the same time, and need some help with a binding. I'm still trying to get my head wrapped around binding controls to properties of a class.

Here is my Malfunctions ViewModel:

public class Malfunctions : ViewModelBase {
       public ObservableCollection<Model.PartMalfunction> AllPartMalfunctions {
            get;
            private set;
        }
       public ObservableCollection<Model.Part> AllParts {
        get;
        private set;
    }
}

Here is the Model.PartMalfunction.cs:

public class PartMalfunction{
        public ObservableCollection<Model.PartSerial> AllPartSerials {
            get;
            set;
        }
    }

Here is the Model.Part.cs:

public class Part {
        public string Label { get; set; }
        public string Value { get; set; }
    }

I have a DataGrid that binds to the AllPartMalfunctions ObservableCollection in the Malfunctions ViewModel. This binding is working just great.

I have another DataGrid nested in the RowDetailsTemplate, and it is binding to AllPartSerials in the PartMalfunction model. This binding is working just fine as well.

My problem is with a combobox that is inside of the nested DataGrid. I want to bind this combobox to the AllParts ObservableCollection in the Malfunctions ViewModel. How do I do this?

<DataGrid ItemsSource="{Binding AllPartMalfunctions}" AutoGenerateColumns="False" Width="Auto"
                        RowDetailsVisibilityMode="Visible">
    <DataGrid.Columns>
    <!--removed for brevity-->
    </DataGrid.Columns>
    <DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <DataGrid ItemsSource="{Binding AllPartSerials }" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox Name="cboPart" VerticalAlignment="Center" ItemsSource="{Binding AllParts}" DisplayMemberPath="Label" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>
Jagd
  • 7,169
  • 22
  • 74
  • 107
  • What is the element that contains the DataGrid bound to AllPartMalFunctions? – Markus Apr 17 '15 at 01:36
  • @Markus - If I understand your question, then you're asking me the hierarchy of controls in the XAML, right? It goes DockingPanel and then StackPanel and then the first DataGrid. – Jagd Apr 17 '15 at 14:59
  • The answer I posted should work. I have some similar code that sets the binding path to commands in the element that contains a DataGrid. I asked for your hierarchy, so that I could understand what is binding to Malfunctions. – Markus Apr 17 '15 at 22:37

2 Answers2

2

A similar approach has been stuck in my case. I realized one with a different view model structure.

public class PartMalfunction{
    public ObservableCollection<Model.PartSerial> AllPartSerials {
        get;
        set;
    }
    public ObservableCollection<Model.Part> AllParts {
        get { return SomeStaticClass.AllParts; }
    }
}

Binding naturally worked even in DataTemplate. Hope this fits to your domain.

dytori
  • 487
  • 4
  • 12
  • 1
    Alternatively this post may help: http://stackoverflow.com/questions/22073740/binding-visibility-for-datagridcolumn-in-wpf – dytori Apr 17 '15 at 04:20
1

Give the element that binds to Malfunctions a Name and bind using a relative path, like shown below in the line containing the ComboBox. I assume for my example that a StackPanel contains the DataGrid and the StackPanel is bound to a Malfunctions property of the container's view model.

<StackPanel x:Name="MalfunctionsGrid" DataContext={Binding Malfunctions}" Orientation="Vertical">
...
    <DataGrid ItemsSource="{Binding AllPartMalfunctions}" AutoGenerateColumns="False" Width="Auto"
                    RowDetailsVisibilityMode="Visible">
    ...
    ...
        <ComboBox Name="cboPart" VerticalAlignment="Center" ItemsSource="{Binding Path=DataContext.AllParts, ElementName=MalfunctionsGrid}" DisplayMemberPath="Label" />
    ...
    ...
Markus
  • 761
  • 3
  • 6