WPF: изменение ItemTemplate ComboBox удаляет возможность переходить по списку при вводе.Есть ли способ это исправить? - PullRequest
10 голосов
/ 10 февраля 2011

PersonVM.cs

public class MainWindowVM
{
    public MainWindowVM()
    {
        PersonList = new ObservableCollection<Person>(Employees);
    }

    private Person[] Employees = new Person[]
    {
        new Person { ID = 1, Name = "Adam" },
        new Person { ID = 2, Name = "Bill" },
        new Person { ID = 10, Name = "Charlie" },
        new Person { ID = 15, Name = "Donna" },
        new Person { ID = 20, Name = "Edward" }
    };

    public ObservableCollection<Person> PersonList { get; set; }
}

Person.cs

public class Person
{
    public string Name { get; set; }
    public int ID { get; set; }
}

MainWindow.xaml (Функциональнорабочая версия - не то, что я хочу отобразить)

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <ComboBox Height="23" Width="300"
                  ItemsSource="{Binding Path=Objects}"
                  DisplayMemberPath="Name"
                  >
        </ComboBox>
    </Grid>
</Window>

MainWindow.xaml (отображается правильно - работает неправильно)

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <ComboBox Height="23" Width="300"
                  ItemsSource="{Binding Path=Objects}"
                  >
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock DataContext="{Binding}">
                        <TextBlock.Text>
                            <MultiBinding StringFormat="{} {0} | {1}">
                                <Binding Path="ID" />
                                <Binding Path="Name" />
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Grid>
</Window>

Второй код отображает то, что я хочу, чтобы ComboBox отображал {ID} | {Name}, но он убирает обычную функцию ComboBox.В первом примере, когда выбран ComboBox, пользователь может начать вводить его и прыгать вниз по списку.Например, если вы нажимаете букву A, она переходит к «Адаму», B переходит к «Биллу» и т. Д. Так должен работать ComboBox.Но когда я перезаписываю ComboBox ItemTemplate, он теряет эту функциональность.Есть ли другой способ связать то, что мне нужно, и сохранить эту функциональность или включить его?Возможно, ItemTemplate настроен неправильно?

1 Ответ

22 голосов
/ 10 февраля 2011

См. Мой ответ на этот вопрос: Могу ли я выполнить поиск текста с помощью мультисвязи

К сожалению, TextSearch.Text не работает в шаблоне данных.Я думаю, у вас есть два варианта здесь

Вариант 1 .Установите для IsTextSearchEnabled значение True для ComboBox, переопределите ToString в исходном классе и измените MultiBinding в TextBlock на Binding

<ComboBox ...
          IsTextSearchEnabled="True">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox> 

public class Person
{
    public override string ToString()
    {
        return String.Format("{0} | {1}", Name, ID);
    }

    public string Name { get; set; }
    public int ID { get; set; }
}

Option 2 .Создайте новое свойство в своем исходном классе, где вы объедините имя и идентификатор для TextSearch.TextPath.Кроме того, вы должны звонить OnPropertyChanged для NameAndId всякий раз, когда вы делаете это для Name или ID

<ComboBox ...
          TextSearch.TextPath="NameAndId"
          IsTextSearchEnabled="True">


public string NameAndId
{
    return String.Format("{0} | {1}", Name, ID);
} 
...