2

我正在尝试使用AutoCompleteBox来自 WPF Toolkit 的搜索字段。AutoCompleteBox 的 Text 属性绑定到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>

视图模型:

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

搜索字段子类:

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

1 回答 1

2

不确定这是否是您想要做的,但我有以下代码,它仅在按下“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();
}

在视图模型中:

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;
        }
    }
}
于 2013-10-10T14:38:36.543 回答