Wpf – Caliburn Micro Bindable collection – binding to combobox item source displays wrong text

bindingcaliburn.microcomboboxwpf

I have this stupid problem. I bind from view model class property type of BindableCollection to the ItemSource property of ComboBox control.

Code from view model class:

public class SpiritUser
{
    public string Nick { get; set; }

    public string Password { get; set; }
}


    public BindableCollection<SpiritUser> SpiritUsers
    {
        get { return _spiritUsers; }
        set
        {
            _spiritUsers = value;
            NotifyOfPropertyChange(() => SpiritUsers);
        }
    }


//constructor of view model class
        public LogOnViewModel()
        {
            SpiritUsers = new BindableCollection<SpiritUser>
                        {
                            new SpiritUser
                                {
                                    Nick = "Spirit_1",
                                    Password = "slniecko1"
                                },
                            new SpiritUser
                                {
                                    Nick = "Spirit_2",
                                    Password = "slniecko1"
                                }
                        };
        }

In view I have this:

  Style on comboBox:

    <Style x:Key="LogOnView_NickComboBox" TargetType="{x:Type ComboBox}">
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Label Content="{Binding Path=Nick}" Grid.Column="0" Grid.Row="0"/>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Height" Value="25"/>
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="Margin" Value="10,4,10,4"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>

ComboBox control:

<ComboBox ItemsSource="{Binding Path=SpiritUsers, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
          Style="{StaticResource LogOnView_NickComboBox}"
          SelectedValuePath="Nick"
          Text="{Binding Path=Nick, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
          SelectedValue="{Binding Path=Nick, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
          IsEditable="True"/>

If I select some comboBox item I see Spirit.Models.SpiritUser instead of item text.

Problem cause if comboBox property IsEditable is set on true.

How can I solve this problem, I need bind property from view model on comboBox but also I need have comboBox editable and bind user input to property in view model.

Best Answer

In case of editable combobox use DisplayMemberPath property instead of ItemTemplate to specify what property of bound object you want to be displayed:

<ComboBox ItemsSource="{Binding Path=SpiritUsers, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
          Style="{StaticResource LogOnView_NickComboBox}"
          DisplayMemberPath="Nick"
          SelectedValuePath="Nick"
          Text="{Binding Path=CurrentUserNick, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
          IsEditable="True"/>

In case if you still want to use ItemTemplate then you can specify what property of you object should be displayed in the text box via TextSearch.TextPath attached property:

<ComboBox ItemsSource="{Binding Path=SpiritUsers, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
          Style="{StaticResource LogOnView_NickComboBox}"
          SelectedValuePath="Nick"
          TextSearch.TextPath="Nick"
          Text="{Binding Path=CurrentUserNick, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
          IsEditable="True"/>
Related Topic