Как предотвратить запуск события SelectionChanged при навигации с помощью клавиатуры в AutoCompleteBox?

Я пытаюсь создать поле поиска, используя AutoCompleteBox из набора инструментов WPF. Свойство Text элемента AutoCompleteBox привязано к свойству в ViewModel, которое реализует INotifyPropertyChanged. Когда свойство изменяется, оно извлекает новые предложения для показа пользователю.

Это испортится, если пользователь использует клавиши со стрелками для просмотра списка предложений автозаполнения, прежде чем выбрать одно — в момент перемещения курсора во всплывающее окно срабатывает SelectionChanged, текстовое поле получает новое значение, а предложения автозаполнения повторяются. собрал. Это также мешает моему желанию использовать событие SelectionChanged для начала поиска.

Есть ли способ предотвратить запуск события SelectionChanged при навигации с помощью клавиатуры?

Вот как у меня все устроено. Примечание. sc:SearchField является подклассом AutoCompleteBox, который предоставляет только способ доступа к свойству TextBox в AutoCompleteBox, поэтому я могу вызывать такие функции, как SelectAll().

XAML:

<sc:SearchField x:Name="SearchField" DataContext="{Binding SearchBoxVm}" Text="{Binding Query, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding QuerySuggestions, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsTextCompletionEnabled="False" Margin="54,10,117,67" Grid.RowSpan="2" BorderThickness="0" FontSize="14" PreviewKeyUp="searchField_OnKeyup" Foreground="{Binding Foreground, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontStyle="{Binding QueryFont, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
        </sc:SearchField>

ViewModel:

void GetQuerySuggestions()
{
    if (!string.IsNullOrEmpty(Query) && !Query.Equals(DEFAULT_TEXT))
    {
        QueryFont = FontStyles.Normal;
        Foreground = Brushes.Black;
        QuerySuggestions = SearchAssistant.GetQueryRecommendations(_query);
    }
}

public string _query = DEFAULT_TEXT;
public string Query
{
    get
    {
        return _query;
    }
    set
    {
        _query = value;
        GetQuerySuggestions();
        NotifyPropertyChanged("Query");
    }
}

List<string> querySuggestions = new List<string>();
public List<string> QuerySuggestions
{
    get { return querySuggestions; }
    set
    {
        querySuggestions = value;
        NotifyPropertyChanged("QuerySuggestions");
    }
}

Подкласс SearchField:

public class SearchField : AutoCompleteBox
{
    public TextBox TextBox 
    { 
        get 
        {
            return (this.GetTemplateChild("Text") as TextBox);
        } 
    }        
}

person BrMcMullin    schedule 15.08.2013    source источник


Ответы (1)


Не уверен, что это то, что вы хотите сделать, но у меня есть следующий код, который изменяет выбор только при нажатии клавиши «Ввод» или использовании мыши для выбора элемента из списка (щелчок левой кнопкой мыши). Я могу без проблем перемещаться вверх и вниз по списку и запускать событие изменения выбора только тогда, когда пользователь нажимает ввод или щелкает нужную запись.

Обратите внимание, что я использую AutoCompleteBox, а не SearchField, как вы.

В XAML:

<toolkit:AutoCompleteBox Name="OmniSearchTextBox"
                         ItemsSource="{Binding CompanyList}" 
                         SelectedItem="{Binding SelectedObject, Mode=TwoWay}"
                         IsTextCompletionEnabled="False" 
                         FilterMode="Contains" 
                         KeyUp="OmniSearch_KeyUp"
                         MouseLeftButtonUp="OmniSearch_MouseLeftButtonUp"
                         Margin="10,94,10,0" 
                         RenderTransformOrigin="0.518,1.92" Height="35"
                         VerticalAlignment="Top" />

В коде позади:

private void OmniSearch_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        BindingExpression exp = this.OmniSearchTextBox.GetBindingExpression(AutoCompleteBox.SelectedItemProperty);
        exp.UpdateSource();
    }
}

private void OmniSearch_MouseLeftButtonUp(object sender, MouseEventArgs e)
{
    BindingExpression exp = this.OmniSearchTextBox.GetBindingExpression(AutoCompleteBox.SelectedItemProperty);
    exp.UpdateSource();
}

В ViewModel:

private const string CompanyListPropertyName = "CompanyList";
private ObservableCollection<Company> _companyList;
public ObservableCollection<Company> CompanyList
{
    get
    {
        return _companyList;
    }
    set
    {
        if (_companyList == value)
        {
            return;
        }

        _companyList = value;
        RaisePropertyChanged(CompanyListPropertyName);
    }

}

private Company _selectedObject;
public Company SelectedObject
{
    get
    {
        return _selectedObject;
    }
    set
    {
        if (_selectedObject != value)
        {
            _selectedObject = value;
        }
    }
}
person BrianKE    schedule 10.10.2013