2

I need to bind a ComboBox's Selected Item according to a value of a field in the data context which it's parent container receives .

the container is a grid which receives it's datacontext from an item in an itemcontrol when it's clicked

private void Button_Click(object sender , RoutedEventArgs e)
{
    GridEmployee.DataContext = ((Button)sender).DataContext;
}

*the Button got it's itemsource from a list of Employee's Bounded to the itemControl

the grid holds some controls amongst them a combobox which i initalize through an Enum

public Enum Gender
{
    Male,Female
};

foreach(string _gender in Enum.GetNames(Gender) )
{
    GenderComboBox.Items.Add(_gender);
}

the Employee class has a matching Property Gender

private string gender;
public string Gender
{
    get{return gender;}
    set
    {
        gender = value ;
        if( PropertyChanged != null )
            PropertyChanged(this,new PropertyChangedEventArgs("Gender"));
    }
}

the GenderComboBox.SelectedItem is bounded to the value of the Gender Property for the bounded object Employee

<ComboBox x:Name="GenderComboBox" SelectedItem="{Binding Gender , Mode=TwoWay}" /> 

the problem here of course that the item does not get selected ..

I tought may be its becuase the items in the combobox are strings and I try to bound them according to a custom converter which just take the Enum Value and returns the .ToString() of it .

but I was not able to check this becuase that threw an An XamlParseException in form's contractor .

which I did not fully understand why it happend ,may be becuase it did not have a value to convert when I form loads.

so to conclude how do I bind a Property from My Employee Class to a combobox with the string representation of the Property's Value?

Yael
  • 1,566
  • 3
  • 18
  • 25
eran otzap
  • 12,293
  • 20
  • 84
  • 139
  • i just saw an example where someone used GenderComboBox.ItemSource = Enum.GetValues(typeof(Gender)) ; so why use item source ? – eran otzap Nov 13 '11 at 14:33
  • "the problem here of course that the item does not get selected". Are you expecting one of the items to show up as selected on the UI when you set the property in code, or are you expecting the property to be set in code when you select one of the items in the UI? Which direction are we going here... – Merlyn Morgan-Graham Nov 13 '11 at 15:01
  • Also I'd recommend using a radio button here instead of a combo box. You can do that with the enum directly using this method: http://stackoverflow.com/questions/397556/wpf-how-to-bind-radiobuttons-to-an-enum – Merlyn Morgan-Graham Nov 13 '11 at 15:02
  • @MerlynMorgan-Graham i just realized what your getting at i should of used a trigger to show the change on the UI right ? i have to use a combobox the gender is just for the example – eran otzap Nov 13 '11 at 16:06
  • @MerlynMorgan-Graham what do you think about setting the ItemSource as the Enum.GetValues(typeof(Gender)) ; – eran otzap Nov 13 '11 at 16:11
  • Doesn't seem like it should make a difference. The question I was asking earlier wasn't rhetorical. :) Are you trying to click on the UI and get the property be set, or are you trying to set the property and get the UI to hilght the item? You shouldn't need a trigger if you're trying to go UI -> property. Not sure if it will work the other way around (?) – Merlyn Morgan-Graham Nov 13 '11 at 16:13
  • im trying to set a property and get the UI highlight them . iv'e got an Employee Class with all sorts of properties i need them to be displayed on the controls in my form. – eran otzap Nov 13 '11 at 16:29
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4953/discussion-between-eran-otzer-and-merlyn-morgan-graham) – eran otzap Nov 13 '11 at 17:07

2 Answers2

2

Works nicely in my case....

XAML

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="GenderSelection" Height="100" Width="300" x:Name="MyWindow">
  <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBlock FontSize="40"
               Text="{Binding MyGender, ElementName=MyWindow, Mode=TwoWay}"/>
    <ComboBox Grid.Row="1"
              ItemsSource="{Binding Genders, ElementName=MyWindow}"
              SelectedItem="{Binding MyGender, ElementName=MyWindow, Mode=TwoWay}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
  </Grid>    
</Window>

Code Behind

public enum Gender
{
    Male,
    Female
}

/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window, INotifyPropertyChanged
{
    private string myGender = Gender.Male.ToString();
    public string MyGender
    {
        get
        {
            return myGender;
        }

        set
        {
            myGender = value;

            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("MyGender"));
            }
        }
    }

    public string[] Genders
    {
        get
        {
            return Enum.GetNames(typeof(Gender));
        }
    }

    public Window1()
    {
        InitializeComponent();
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
  }

Let me know if this guides you in correct direction...

WPF-it
  • 19,625
  • 8
  • 55
  • 71
  • I got a question for you about your answer. Where is the line between adding the Genders array to the code behind and adding it to the ViewModel? For me it seems like both the enum and array should be a part of the DataContext... – CodeMonkey Mar 29 '14 at 14:07
0

Just change the initialization of your ComboBox to

foreach(string _gender in Enum.GetNames(Gender) ) 
{ 
   GenderComboBox.Items.Add(_gender.ToString()); 
} 

That should work, because your Gender property of the Employees class returns a string.

Fischermaen
  • 12,238
  • 2
  • 39
  • 56