0
votes

I'm creating my first WPF application (have done a few with WinForms earlier), and I'm starting to like it (even if it adds more complexity than necessary sometimes..). But I've hit a problem that I can't really figure out.

The Problem: I have a TreeView and a companion GroupBox with properties of the selected (2nd level) item. The properties are editable in TextBoxes (bind to SelectedItem.[Property]) and that works fine. But one of the properties is a list (defined as ObservableCollection), that I want to display in a ComboBox, so I bound ItemsSource to the SelectedItem.Modes of the TreeView:

<ComboBox Name="FixtureModesListBox" ItemsSource="{Binding ElementName=FixturesTreeView, Path=SelectedItem.Modes}" ItemTemplate="{StaticResource FixtureModeTemplate}" />

Which, apparently, doesn't work, the error I get says:

 BindingExpression path error: 'Modes' property not found on 'object' ''efcFixtureModel' ...

The property does exist, is set, is public etc.

My current solution I can get it to work, by using some codebehind (and referencing the exact same "path"):

    private void FixturesTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (FixturesTreeView.SelectedItem is efcFixtureModel) // The 1st level/parent items is of a different type
        {
            FixtureModesListBox.ItemsSource = (FixturesTreeView.SelectedItem as efcFixtureModel).Modes;
        }
    }

I can't wrap my brain around why this isn't working and I haven't find any good info on the net.

Edited to include more info:

<TreeView Name="FixturesTreeView" ItemTemplate="{StaticResource FixtureItemTemplate}" SelectedItemChanged="FixturesTreeView_SelectedItemChanged">
</TreeView>

...
        // Assignment of ItemsSource
        FixturesTreeView.ItemsSource = mainWin.Companies;
...

public partial class efcMainWindow : Window
{
    // Definition of Companies
    public ObservableCollection<efcCompany> Companies;

...

// Definition of efcCompany    
public class efcCompany
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public string Logo { get; set; }
    public int FixtureCount { get { return Fixtures.Count; } }
    public ObservableCollection<efcFixtureModel> Fixtures { get; set; }

    public efcCompany(string name = "", int id = -1, string url = "", string logo = "")
    {
        this.Name = name;
        this.Id = id;
        this.Url = url;
        this.Logo = logo;

        this.Fixtures = new ObservableCollection<efcFixtureModel>();
    }

    public override string ToString()
    {
        return "#" + Id.ToString() + ": " + Name + " (" + Url + ", " + Logo + ")";
    }
}

// Definition of efcFixtureController
public class efcFixtureModel
{
    public int Id { get; set; }
    public int Manufacturer { get; set; }
    public efcFixtureType Type { get; set; }
    public string Name { get; set; }
    public string Image { get; set; }
    public string Description { get; set; }

    public byte TotalChannelCount { get; set; }

    public ObservableCollection<efcFixtureMode> Modes;

    public efcFixtureModel()
    {
        Modes = new ObservableCollection<efcFixtureMode>();
    }

    public override string ToString()
    {
        return "#" + Id.ToString() + ": " + Name + " (" + Type.ToString() + ", " + Image + ", " + Description + ")";
    }
}
2

2 Answers

0
votes

You need to convert your efcFixtureModel.Modes from Field to Property:

public ObservableCollection<efcFixtureMode> Modes { get; set; }

Please read What is Difference between Property and Variable in C#

0
votes

As I said before, you need bind the SelectedItem from FixturesTreeView to a property of type efcFixtureModel in ViewModel.

<TreeView Name="FixturesTreeView" ItemTemplate="{StaticResource FixtureItemTemplate}" SelectedItemChanged="FixturesTreeView_SelectedItemChanged"
SelectedItem="{Binding TreeViewSelectedItem}">
</TreeView>

<ComboBox Name="FixtureModesListBox" ItemsSource="{Binding TreeViewSelectedItem.Modes}" ItemTemplate="{StaticResource FixtureModeTemplate}" />