2013-12-06 1 views
2

Моя цель - позволить пользователю нажать клавишу табуляции и автозаполнение, чтобы сразу выбрать первый элемент в раскрывающемся списке. Проблема в том, что я не могу понять, как получить доступ к первому фильтруемому элементу. Есть идеи?Как отфильтровать список элементов для первого совпадения в AutoCompleteBox?

Сначала я думал, что свойство IsTextCompletionEnabled = true решит мою проблему. Но если я использую FilterMode = Contains, функция textcompletion не поможет, потому что ничего не завершено.

The ItemsSource на самом деле не меняется. Мне нужно перейти к первому элементу в отфильтрованном списке, а не к источнику items. Есть ли способ?

Вот мой код:

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      List<Recording> MyMusic = new List<Recording>(); 

      MyMusic.Add(new Recording("Chris Sells", "Chris Sells Live", new DateTime(2008, 3, 5))); 
      MyMusic.Add(new Recording("Chris Sells", "CSells Tells", new DateTime(2004, 4, 6))); 
      MyMusic.Add(new Recording("Luka Abrus", "The Road to Redmond", new DateTime(2007, 8, 3))); 
      MyMusic.Add(new Recording("Luka Abrus", "CLuka", new DateTime(2005, 12, 8))); 
      MyMusic.Add(new Recording("Luka Abrus", "CLove and Luka", new DateTime(2005, 12, 8))); 
      MyMusic.Add(new Recording("Jim Hance", "The Best of Jim Hance", new DateTime(2007, 2, 6))); 

      Records.ItemsSource = MyMusic; 
     } 

     private void Records_KeyDown(object sender, KeyEventArgs e) 
     { 
      if (e.Key == Key.Tab) 
       Records.SelectedItem = ((IEnumerable<object>)Records.ItemsSource).First(); 
     } 
    } 

    public class Recording 
    { 
     public Recording() { } 
     public Recording(string artistName, string cdName, DateTime release) 
     { 
      Artist = artistName; 
      Name = cdName; 
      ReleaseDate = release; 
     } 
     public string Artist { get; set; } 
     public string Name { get; set; } 
     public DateTime ReleaseDate { get; set; } 
    } 

А вот XAML:

<Controls:AutoCompleteBox x:Name="Records" HorizontalAlignment="Left" Margin="164,142,0,0" VerticalAlignment="Top" Width="182" 
          ValueMemberPath="Name" KeyDown="Records_KeyDown" 
          FilterMode="Contains" 
          IsTextCompletionEnabled="True"> 
    <Controls:AutoCompleteBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Name}"/> 
     </DataTemplate> 
    </Controls:AutoCompleteBox.ItemTemplate> 
</Controls:AutoCompleteBox> 

ответ

2

Вам просто нужно передать предикат методу First,

private void Records_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Tab) 
     { 
      Records.SelectedItem = 
       Records.ItemsSource 
        .First(item => 
         item.Name.Contains(textBoxValue) || 
         item.Artist.Contains(textBoxValue)); 
     } 
    } 

Таким образом, выбранный элемент будет первым, совпадающим с предикатом, или в этом случае первым, где элемент имя или исполнитель содержит текущее значение в текстовом поле.

+1

Awesome работал как шарм. Чтобы заставить его работать, мне пришлось сделать его более конкретным для моей ситуации, но это отлично работает. Вот что я сделал: если (e.Key == Key.Tab) { Records.SelectedItem = ((IEnumerable ) Records.ItemsSource) .Первый (пункт => item.Name.Contains (записей. Текст) || item.Artist.Contains (Records.Text)); –

+0

Кстати, вам не нужно указывать его на 'IEnumerable '; a «Список ' уже реализует 'IEnumerable ', поэтому преобразование не требуется, как показано в ответе. – rae1

+0

Вот что я и подумал. Но по какой-то причине в моем коде Records.ItemsSource появляется IEnumerable (Not IEnumerable , просто IEnumerable). Я не знаю почему. –

-1

Records.SelectedItem = Records.Items [0]; ?

+1

-1 Это не фильтрует элементы, оно просто возвращает первый, который может не соответствовать входу. – rae1