6
<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>
Technocrat
  • 334
  • 1
  • 4
  • 15
  • 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 and an ObservableCollection. – Lee O. Aug 10 '14 at 00:07
  • And please mark my answer if that is what fixed it. – Lee O. Aug 10 '14 at 00:22
  • Could I do the same thing with 'Character' that i'm doing with 'charList', will it work the same way? – Technocrat Aug 10 '14 at 00:22
  • 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. Aug 10 '14 at 00:26
  • Why does my new code throw an exception then? TargetInvocationException was Unhandled @LeeO. – Technocrat Aug 10 '14 at 00:34
  • Create a new question with the exception and only the section of code where the exception is occurring. – Lee O. Aug 10 '14 at 00:39

1 Answers1

22

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.

Lee O.
  • 3,212
  • 2
  • 26
  • 36
  • doesn't have ItemsSource though, it only has a Binding Path to the content of the label? Does this count as defining it twice? Ohhh I understand, so if I get rid of it, it now shows the Object location "ItemControl.Character" instead of the Character. How else should I edit it to do what I want? – Technocrat Aug 09 '14 at 23:51
  • You are adding another ComboBoxItem to the ComboBox with that code. Just like TEXT THAT WILL DISPLAY applies the text to the TextBox. will add that ComboBoxItem to the ItemsSource. – Lee O. Aug 09 '14 at 23:54
  • What you really wanted to do was define templates to use for the ComboBoxItems. You are going to have to use a ItemTemplateSelector to allow for different Templates unless you make Character a base class and then have the different character types as subclasses. Then you could create DataTemplates for the different items based on their data type. – Lee O. Aug 09 '14 at 23:55