5
votes
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1.5*"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>  



    <Grid Grid.Column="0" Background="DarkCyan">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>    
            <ComboBox ItemsSource="{Binding Path=charList}" x:Name="comboBox" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="2">
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="Pictures\bagi_warrior.jpg" Width="100" Height="150"/>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition Height="6*"/>
                        </Grid.RowDefinitions>
                        <Label Grid.Row="0" Content="{Binding Path=Character.Name}" FontSize="30"/>
                        <Label Grid.Row="1" Content="{Binding Path=Character.Level}" FontSize="20"/>
                    </Grid>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="Pictures\azure_knight.jpg" Width="100" Height="130"/>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition Height="6*"/>
                        </Grid.RowDefinitions>
                        <Label Grid.Row="0" Content="Azure Knight"  FontSize="30"/>
                        <Label Grid.Row="1" Content="Level 158"  FontSize="20"/>
                    </Grid>
                </StackPanel>
            </ComboBoxItem>
        </ComboBox>
        <Label x:Name="strLabel" Grid.Column="0" VerticalAlignment="Bottom" Height="30" Content="Str: " HorizontalContentAlignment="Center" FontSize="16"/>
        <Label x:Name="intLabel" Grid.Column="1" VerticalAlignment="Bottom" Height="30" Content="Int: " HorizontalContentAlignment="Center" FontSize="16"/>
        <Label x:Name="dexLabel" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" Height="30" Content="Dex: " HorizontalContentAlignment="Center" FontSize="16"/>
        <Label x:Name="goldLabel" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Height="30" Content="Gold: " HorizontalContentAlignment="Center" FontSize="16"/>


    </Grid>
    <Grid Grid.Column="1">
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <DataGrid x:Name="MyGrid" ItemsSource="{Binding Path=Item}"></DataGrid>
    </Grid>
</Grid>

My XAML is such, it looks like this:

http://puu.sh/aLLrx.png

http://puu.sh/aLLsQ.jpg

my code is:

 public partial class MainWindow : Window
 {

    Character aloken;
    Character azureKnight;
    Character bagiWarrior;
    Character incarMagician;
    Character segitaHunter;
    Character segnale;
    Character viciousSummoner;
    private List<Character> _charList = new List<Character>();

    public MainWindow()
    {
        InitializeComponent();
        charList.Add(new Character("Bagi Warrior"));
        this.Item = new ObservableCollection<Item>();
        this.Character = new ObservableCollection<Character>();

        this.DataContext = this;
        //Character.Add(new Character(name: "Bagi Warrior", level: 197, characterClass: CharacterClass.Bagi_Warrior, gender: Gender.Male, strength: 450, intelligence: 4, dexterity: 84, gold: 147203352));
        //Character.Add(new Character(name: "Azure Knight", level: 158, characterClass: CharacterClass.Azure_Knight, gender: Gender.Male, strength: 390, intelligence: 120, dexterity: 92, gold: 204220567));
        //Character.Add(new Character(name: "Incar Magician", level: 169, characterClass: CharacterClass.Incar_Magician, gender: Gender.Female, strength: 4, intelligence: 512, dexterity: 57, gold: 172223520));
        //Character.Add(new Character(name: "Vicious Summoner", level: 203, characterClass: CharacterClass.Vicious_Summoner, gender: Gender.Male, strength: 423, intelligence: 89, dexterity: 45, gold: 114225587));

    }

    public List<Character> charList
    {
        get { return _charList; }
        set { _charList = value; }
    }


    private ObservableCollection<Character> _Character;

    public ObservableCollection<Character> Character
    {
        get { return _Character; }
        set { _Character = value; }
    }


    private ObservableCollection<Item> _Item;
    public ObservableCollection<Item> Item
    {
        get { return _Item; }
        set { _Item = value; }
    }

}

Character Class (just in case): http://pastebin.com/GFycKqDC

Item Class (just in case): http://pastebin.com/RgXzbFHk

It's a project on a RPG where you have to use databinding for a combobox and to create an ObservableCollection for the combobox and view each Character.

The issue i'm running into is: In my combobox, I want to be able to display the Character with their 'image' and next to it, their 'level' and 'name'

But I don't want it to be static, I want to create a list of Characters and bind the ItemsSource to my ComboBox so that no matter which character I select, information based on that character will update. How do I do this?

I was told that creating a List of Characters, then make a data template for ComboBox Item that holds a pic, name, and level that are bound to selectedItem would do the job (which I did called charList) but whether I do it in code, or in XAML, it throws an exception saying that the collection must be empty before I bind to it.

I want to bind the properties in the datatemplate to selectedItem so that the labels and information will update appropriately.

What am I doing wrong, and why is this exception being thrown?

EDIT

Okay so now the problem is fixed! However, why does my Label binding still not work for Character.Name and Character.Level?

http://puu.sh/aLPr7.jpg

EDIT 2 public MainWindow() { InitializeComponent(); Character.Add(new Character("Bagi Warrior")); Character.Add(new Character("Azure Knight")); this.Item = new ObservableCollection(); this.Character = new ObservableCollection();

        this.DataContext = this;
        //Character.Add(new Character(name: "Bagi Warrior", level: 197, characterClass: CharacterClass.Bagi_Warrior, gender: Gender.Male, strength: 450, intelligence: 4, dexterity: 84, gold: 147203352));
        //Character.Add(new Character(name: "Azure Knight", level: 158, characterClass: CharacterClass.Azure_Knight, gender: Gender.Male, strength: 390, intelligence: 120, dexterity: 92, gold: 204220567));
        //Character.Add(new Character(name: "Incar Magician", level: 169, characterClass: CharacterClass.Incar_Magician, gender: Gender.Female, strength: 4, intelligence: 512, dexterity: 57, gold: 172223520));
        //Character.Add(new Character(name: "Vicious Summoner", level: 203, characterClass: CharacterClass.Vicious_Summoner, gender: Gender.Male, strength: 423, intelligence: 89, dexterity: 45, gold: 114225587));

    }

    //public List<Character> charList
    //{
    //    get { return _charList; }
    //    set { _charList = value; }
    //}


    private ObservableCollection<Character> _Character;

    public ObservableCollection<Character> Character
    {
        get { return _Character; }
        set { _Character = value; }
    }

and then XAML:

<Grid Grid.Column="0" Background="DarkCyan">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ComboBox ItemsSource="{Binding Path=Character}" x:Name="comboBox" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="2">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image x:Name="image" Source="{Binding Source={StaticResource ImageConverter}}" Width="100" Height="150"/>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="6*"/>
                            </Grid.RowDefinitions>
                            <Label Grid.Row="0" Content="{Binding Path=Character.Name}" FontSize="30"/>
                            <Label Grid.Row="1" Content="{Binding Path=Character.Level}" FontSize="20"/>
                        </Grid>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
1
Each ComboBoxItem has an instance of Character as it's DataContext so the correct path is Name and Level. It's looking for a property called Character that itself has a property Name. Not sure why you have a List<Character> and an ObservableCollection<Character>.Lee O.
And please mark my answer if that is what fixed it.Lee O.
Could I do the same thing with 'Character' that i'm doing with 'charList', will it work the same way?Technocrat
You typically use the ObservableCollection as the type for any collection you are binding to as an ItemsSource because it will notify the binding when you add/remove from the collection whereas List will not.Lee O.
Why does my new code throw an exception then? TargetInvocationException was Unhandled @LeeO.Technocrat

1 Answers

19
votes

You are defining the ItemsSource twice.

Once using

ItemsSource="{Binding charList}"

and then again with

<ComboBoxItem>

You will want to replace the ComboBoxItem element with ComboBox.ItemTemplate and create a DataTemplate for your ComboxItem. Then you'll want to either bind the Image Source to a property on the Character class or use a ItemTemplateSelector to have it use the appropriate DataTemplate for the item. If only the image source location is changing, you could also use a datatrigger bound to the property defining the character class.