开发者

How do I add type-down support to a WPF ComboBox?

开发者 https://www.devze.com 2023-01-07 02:51 出处:网络
This is my ComboBox: <ComboB开发者_Python百科ox Name=\"ApplicationList\" MinWidth=\"200\" Margin=\"4\" >

This is my ComboBox:

            <ComboB开发者_Python百科ox Name="ApplicationList" MinWidth="200" Margin="4" >
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding ApplicationName}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>

If the combo box contains just strings I get type-down support for free. But how do I enable type-down support for complex objects?


Set TextSearch.TextPath to the property name:

<ComboBox Name="ApplicationList" TextSearch.TextPath="ApplicationName" MinWidth="200" Margin="4">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ApplicationName}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

From the documentation:

Use this property on a control that contains a collection of items. The value of the specified property is the text that the user can type to select the item, and the text that is displayed if the control is set to display text in its TextBox.

EDIT: Setting IsEditable to True isn't necessary.


I see that you don't want to override ToString() in your Model, which makes sense. But if you're binding your View (the xaml code) to your Model then you're missing out on the benefits of having a middle-man: the ViewModel.

What I would do in your situation is to wrap the individual items in ApplicationList with a ViewModel. Let's assume that ApplicationList is a collection of type ApplicationModel, so perhaps ObservableCollection. If you change this to ObservableCollection<**ApplicationViewModel>, where each **ApplicationViewModel has a private reference to an ApplicationModel you can go crazy with the representation of that object. You could throw in ToString, DateTime of creation, and all things relevant to a user interface without having to monkey with your Model.

public class ApplicationViewModel
{
   private ApplicationModel _application;
   private DateTime _creationDate;

   public ApplicationViewModel(ApplicationModel application)
   {
      _application = application;
      _creationDate = DateTime.Now;
   }

   public override string ToString()
   {
      return _application.ApplicationName + ", " + _creationDate.ToString();
   }

}

The point is that no class can touch your ApplicationModel class except through the tight control of the ApplicationViewModel class, while giving you the full ability to play around with things relevant to the user interface. Do this with every class, and you'll never look back. Another bonus is that you can test your Model classes very easily without the UI stuff getting in the way.


There are two ways to get this working again. If you're doing something that's actually as simple as your example you can just set

DisplayMemberPath="ApplicationName"

instead of specifying an ItemTemplate.

If you need more options for formatting your items that require using an ItemTemplate set TextSearch.TextPath to the property that you want to do text selection on:

TextSearch.TextPath="ApplicationName"


A workaround is to override the ToString method on the model, but I am looking for a more general solution.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号