1

In my WPF application, I have a ListBox in my main screen. I'm trying to use the MVVM pattern, so I have a ViewModel associated with the View. When I launch the application, my ViewModel gets initiated, and it reads in a bunch of DLLs I've placed in a directory. Each DLL contains a "Strategy" class, so when I read the DLLs, I retrieve these Strategy class objects and put them in a list (actually an ObservableCollection) which is a member of my ViewModel. I'm using this member list, named DllList, to populate the ListBox.

My ViewModel looks like the following (unnecessary bits removed for clarity):

public class ViewModelPDMain : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public ViewModelPDMain() {
        dllList = new ObservableCollection<Strategy>();
        selectedStrategy = new Strategy();
    }

    private ObservableCollection<Strategy> dllList = null;
    private Strategy selectedStrategy = null;
    public ObservableCollection<Strategy> DllList
    {
        get { return dllList; }
        set {
            dllList = value;
            RaisePropertyChanged("DllList");
        }
    }

    public Strategy SelectedStrategy
    {
        get { return selectedStrategy; }
        set {
            selectedStrategy = value;
            RaisePropertyChanged("SelectedStrategy");
        }
    }
}

Then in my main View, I bind it as follows.

<Window x:Class="PrisonersDilemma.Source.View.ViewPDMain"
        xmlns:local="clr-namespace:PrisonersDilemma.Source.View"
        DataContext="{Binding Source={StaticResource mainViewModelLocator}, Path=ViewModelPDMain}"
        Title="Iterated Prisoner's Dilemma" Height="500" Width="800" MinHeight="500" MinWidth="800">
    <Grid Name="gridMain">
        ...
        <!-- More stuff here -->
        ...
        <ListBox Name="listStrategies" SelectedIndex="0"
                 ItemsSource="{Binding DllList}" SelectedItem="{Binding SelectedStrategy}"
                 Grid.Column="0" Grid.Row="1" Grid.RowSpan="2"
                 Width="Auto" MinWidth="120"
                 Margin="3"
                 BorderBrush="LightGray" BorderThickness="1">

        </ListBox>
        ...
        <!-- More stuff here -->
        ...
    </Grid>
</Window>

When I do this and run the application my list box looks like below which is expected.

enter image description here

The problem is when I try to display a property inside my Strategy objects. My Strategy class contains another class, named StratInfo, which in turn contains a string property, StrategyName. My requirement is to display this string value as listbox item values instead of what you can see above.

So I do the following in my View:

<Window x:Class="PrisonersDilemma.Source.View.ViewPDMain"
        xmlns:local="clr-namespace:PrisonersDilemma.Source.View"
        DataContext="{Binding Source={StaticResource mainViewModelLocator}, Path=ViewModelPDMain}"
        Title="Iterated Prisoner's Dilemma" Height="500" Width="800" MinHeight="500" MinWidth="800">
    <Grid Name="gridMain">
        ...
        <!-- More Stuff Here -->
        ...
        <ListBox Name="listStrategies" SelectedIndex="0"
                 ItemsSource="{Binding DllList}" SelectedItem="{Binding SelectedStrategy}"
                 Grid.Column="0" Grid.Row="1" Grid.RowSpan="2"
                 Width="Auto" MinWidth="120"
                 Margin="3"
                 BorderBrush="LightGray" BorderThickness="1">
            <!-- Added Stuff -->
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Label Name="lblFirstName" 
                               Content="{Binding SelectedStrategy.StratInfo.StrategyName, Mode=OneWay}"
                               Grid.Column="0"></Label>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        ...
        <!-- More Stuff Here -->
        ...
    </Grid>
</Window>

When I do this, I expect the list box items to contain a label, and it to display my StrategyName value. However, I get a listbox which contains 25 items (I have 25 DLLs), but all 25 items are empty.

Funny thing is, I tried to bind the SelectedStrategy.StratInfo.StrategyName to a text box Text property, and it worked. That is, when I click any empty listbox item, it displays the StrategyName in the text box. Please refer to the following figure. You can see that the listbox contains items but the content values aren't displayed. In addition, to the right, the Strategy Name text box is a text box where I have bound the SelectedStrategy.StratInfo.StrategyName and it displays the correct value on item select event.

enter image description here

I have done this exact same thing in a simpler project, and it works just fine. I can't figure out what I'm doing wrong here.

Any thoughts?

1 Answer 1

3

Your binding in the data template is incorrect. The data context within the data template is an item in the DllList which is of type Strategy. So your Label should be like so:

<Label Name="lblFirstName"
       Content="{Binding StratInfo.StrategyName, Mode=OneWay}"
       Grid.Column="0"/>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.