2
votes

I have a combobox which binds to ObservableCollection<CustomerViewModel>

<ComboBox ItemsSource="{Binding AllCustomers}" IsEditable="True"/>

If I use DisplayMemberPath property, the dropdown and the selecteditem displays correctly

<ComboBox ItemsSource="{Binding AllCustomers}" DisplayMemberPath="CustomerName" IsEditable="True"/>

enter image description here

But if a DataTemplate is assigned, the selecteditem is not displayed properly

<ComboBox ItemsSource="{Binding AllCustomers}" SelectedValue="CustomerName" IsEditable="True">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding CustomerName}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ComboBox>

enter image description here

Edit: I found the issue, but not the solution, and the issue is if the ComboBox has IsEditable="True" it creates the problem.


Code abstract:

public class AllCustomersViewModel
{
   public ObservableCollection<CustomerViewModel> AllCustomers {get; set;}
}

public class CustomerViewModel
{
   public string CustomerName;
   public short CustomerID;
}

Which property is to be set (or how) to display the selectedvalue/item correctly.

Thank you very much in advance.



ActualCode

public class AccountTransactionsViewModel
{
    DataRepository _repository;

    public AccountTransactionsViewModel()
    {
        _repository = new DataRepository();
        CreateAccountsViewModel();
    }

    public ObservableCollection<AccountViewModel> AllAccounts { get; set; }

    void CreateAccountsViewModel()
    {
        List<AccountViewModel> allAccounts = _repository.GetAccounts()
                                                        .Select(a => new AccountViewModel(a, _repository))
                                                        .ToList();

        AllAccounts =  new ObservableCollection<AccountViewModel>(allAccounts);            
    }
}



  public class AccountViewModel
  {
       Account _account;
       DataRepository _repository;

       public AccountViewModel(Account account, DataRepository repository)
       {
            _account = account;
            _repository = repository;
       }

       public short AccountID { get { return _account.AccountID; } set { } }
       public string AccountName { get { return _account.AccountName; } set { } }        
  }

XAML:

<ComboBox Name="customerCombobox" ItemsSource="{Binding AllAccounts}" IsEditable="True">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding AccountName}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>                     
                    </ComboBox>

Edit:

I found the issue, but not the solution, and the issue is if the ComboBox has IsEditable="True" it creates the problem.

4
Something is messed up in your sample: you have AccountName in code and CustomerName in XAML. Can you post your actual code? Because setting the ItemTemplate should effect the also the selected item as well and your code should work.nemesv
@nemesv: Oh yes sorry.. I corrected it. THis happend coz i manually typed the dataclasses here.Marshal
check for binding errors in the output in VS, they'll give a hint on the reason why this fails. Also I am not sure setting SelectedValue like that works.stijn
@stijn There are absolutely no BindingExpression errors in output. :(Marshal

4 Answers

3
votes

The full name of the object's type is displayed when there's no template available. Also the full type name is the result of the ToString() method call. So either override ToString() method or investigate more about the data templates.

0
votes

Try

<ComboBox ItemsSource="{Binding AllCustomers}" SelectedValue="CustomerName">
        <ItemsControl.ItemTemplate>
             <DataTemplate>
                 <TextBlock Text="{Binding Item.CustomerName}"/>
             </DataTemplate>
        </ItemsControl.ItemTemplate>
</ComboBox>
0
votes

If want to show the selected values some property you should use the SelectedValuePath. SelectedValue will hold the value of the SelectedItems property you want to show.

Without setting the SelectedValuePath the framework tries to get back whole SelectedItem - in this case AccountViewModel instance - converted to string

<ComboBox Name="customerCombobox" ItemsSource="{Binding AllAccounts}" SelectedValuePath="AccountName">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding AccountName}"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>                     
                </ComboBox>
0
votes

I had the same problem because I wanted to display a custom text in the combobox items. When you have an ItemTemplate you cannot set the DisplayMemberPath of the ComboBox displays the class name when you don't have the toString() function implemented.

You just have to use TextSearch.TextPath and your problem is solved.

<ComboBox IsEditable="True" TextSearch.TextPath="MySelectedTextField">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock ToolTip="{Binding MyTooltipField}">
                <Run Text="{Binding MyCustomField1}" />
                <Run Text=" - "/>
                <Run Text="{Binding MyCustomField2}" />
            </TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>