11

I'm new to WPF And I have a question. I have the Organization module:

class Organization : ObservableObject
{
    public string OrganizationName { get; set; }
}

I have the ViewModel of the Organization:

class OrganizationViewModel : ObservableObject
{
    int _count = 0;

    public OrganizationViewModel()
    {
        Organization = new Organization {OrganizationName = "New Organization"};
    }

    public Organization Organization { get; set; }

    public string OrganizationName
    {
        get { return Organization.OrganizationName; }
        set
        {
            if(Organization.OrganizationName != value)
            {
                Organization.OrganizationName = value;
                RaisePropertyChanged("OrganizationName");
            }
        }
    }

And I have the ViewModel of all the Organizations:

class AllOrganizationsViewModel
    {
        private ObservableCollection<OrganizationViewModel> m_organizations = new ObservableCollection<OrganizationViewModel>();


    public ObservableCollection<OrganizationViewModel> Organizations
    {
        get { return m_organizations; }
        set { m_organizations = value; }
    }

    public AllOrganizationsViewModel()
    {
        for(int i = 0; i < 3; ++i)
        {
            m_organizations.Add(new OrganizationViewModel());
        }
    }

    void AddOrganizationNameExecute()
    {
        m_organizations.Add(new OrganizationViewModel());
    }

    bool CanAddOrganizationNameExecute()
    {
        return true;
    }

    public ICommand AddOrganization{get{return new RelayCommand(AddOrganizationNameExecute, CanAddOrganizationNameExecute);}}

}

And this is the MainWindow.xaml:

<Window x:Class="DataIntegrityChecker.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataIntegrityChecker.ViewModels" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:AllOrganizationsViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="285*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="156" />
            <ColumnDefinition Width="347*" />
        </Grid.ColumnDefinitions>
        <Label Content="Organization: " Margin="0,0,44,0" />
        <Button Grid.Row="1" Name="UpdateOrganizations" Content="Update Organization Name" Command="{Binding AddOrganization}" Margin="0,0,0,262" HorizontalAlignment="Left" Width="156" />
        <ComboBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Name="comboBox1" VerticalAlignment="Top" Width="155"  ItemsSource="{Binding Organizations}" />
    </Grid>
</Window>

Now, what I get in the ComboBox items is the name of the class OrganizationViewModel but what I need is the OrganizationName string. It seems to me that I have some binding to OrganizationName that's missing but I can't figure out where to add if (if that's the issue). I assume I can make a collection of strings with the names of the organizations I need. But in the future I will need more properties in the Organization Class so that's the way I need it to work.

I will appreciate any help

MentalBrake
  • 157
  • 1
  • 2
  • 8

3 Answers3

24

You need to add DisplayMemberPath:

<ComboBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Name="comboBox1" VerticalAlignment="Top" Width="155"  ItemsSource="{Binding Organizations}"
          DisplayMemberPath="OrganizationName"/>
Vyacheslav Volkov
  • 4,592
  • 1
  • 20
  • 20
  • Great! thanks it works, I think I actually tried it so I probably got it wrong. – MentalBrake Apr 24 '13 at 17:08
  • 1
    This is nearly impossible to debug. When nothing shows up in the list, how is anyone supposed to know that such an attribute is missing? It didn't work for me anyway. I have ItemSource bound to an ObservableCollection on my DataContext. `ItemsSource="{Binding Projects, Mode=OneWay}"`, where `Projects` is the property name of the ObservableCollection on my data context object instance. – Triynko Feb 11 '14 at 23:03
  • 3
    Ensure that you are using the correct `DisplayMemberPath`, it should be a property with public accessor. Also, if you have the binding errors, you can see them in VS using the `Output Window` during debugging. – Vyacheslav Volkov Feb 12 '14 at 02:37
8

Another way can be by defining ItemTemplate. It gives more flexibility on display

   <ComboBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Name="comboBox1" VerticalAlignment="Top" Width="155"  ItemsSource="{Binding Organizations}" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding OrganizationName}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
Rohit Agrawal
  • 335
  • 1
  • 2
  • 9
0

Hi this is my suggestion to solve your question:

code behind:

 private ObservableCollection<customObj> customObjs = new ObservableCollection<customOb>();
 public ObservableCollection<customObj> CustomObjs
    {
        get => customObj;
        set
        {
            customObj = value;
        }
    }

and

public class customObj
{
    private uint number;
    public uint Number
    {
        get { return number; }
        set
        {
            if (number != value)
            {
                number = value;
            }
        }
    }
}

in Xaml file:

<Style x:Key="ComboBoxCustomObjStyle" TargetType="{x:Type ComboBox}">
    <Setter Property="ItemsSource" Value="{Binding Path=CustomObjs}"/>
    <Setter Property="DisplayMemberPath" Value="Number"/>
    <Setter Property="SelectedValuePath" Value="Number"/>
    <Setter Property="SelectedValue" Value="0"/>
</Style>  
<ComboBox x:Name="CbSelectCustomObj"               
                  Style="{StaticResource ComboBoxCustomObjStyle}"/>

Keep in mind ,before to show the combobox make sure the observablecollection was populated!

luka
  • 605
  • 8
  • 15