如何防止AutoCompleteBox中的键盘导航触发SelectionChanged事件?

时间:2013-08-15 00:14:45

标签: wpf xaml autocomplete wpftoolkit selectionchanged

我正在尝试使用WPF Toolkit中的AutoCompleteBox构建搜索字段。 AutoCompleteBox的Text属性绑定到ViewModel中实现INotifyPropertyChanged的属性。更改属性后,它会获取要向用户显示的新建议。

如果用户在选择自动完成建议列表之前使用箭头键扫描自动完成建议列表,则会变得混乱 - 当光标移动到弹出窗口时,SelectionChanged被触发,文本字段获得新值,并重新收集自动填充建议。这也会影响我使用SelectionChanged事件开始搜索的愿望。

有没有办法阻止在键盘导航中触发SelectionChanged事件?

以下是我设置的方法。注意sc:SearchFieldAutoCompleteBox的子类,仅提供访问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>

视图模型:

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);
        } 
    }        
}

1 个答案:

答案 0 :(得分:1)

不确定这是否是您想要做的,但我有以下代码,只有在按下'Enter'键或使用鼠标从列表中选择项目时更改选择(单击鼠标左键) )。我可以毫无问题地向上和向下滚动列表,只有当用户按下Enter或点击所需的条目时才会触发选择更改事件。

请注意,我正在使用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;
        }
    }
}