2

AutoCompleteBoxWPF Toolkitを使用して検索フィールドを構築しようとしています。AutoCompleteBox の Text プロパティは、ViewModelを実装する のプロパティにバインドされていますINotifyPropertyChanged。プロパティが変更されると、ユーザーに表示する新しい提案がフェッチされます。

ユーザーが矢印キーを使用してオートコンプリート候補のリストをスキャンしてから 1 つを選択すると、これは混乱します。カーソルがポップアップに移動した瞬間にSelectionChanged、テキスト フィールドが新しい値を取得し、オートコンプリート候補が再収集されます。 . SelectionChangedこれはまた、イベントを使用して検索を開始したいという私の欲求を妨げます。

キーボード ナビゲーションで SelectionChanged イベントが発生しないようにする方法はありますか?

これが私が物事をセットアップする方法です。sc:SearchFieldのサブクラスであり、のプロパティにAutoCompleteBoxアクセスする方法のみを提供するため、次のような関数を呼び出すことができますTextBoxAutoCompleteBoxSelectAll()

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

1 に答える 1

2

これがあなたがやりたいことかどうかはわかりませんが、「Enter」キーが押されたとき、またはマウスを使用してリストから項目を選択したとき (マウスの左ボタンをクリックしたとき) にのみ選択を変更する次のコードがあります。問題なくリストを上下に移動でき、ユーザーがEnterキーを押すか、目的のエントリをクリックしたときにのみ選択変更イベントを発生させます。

あなたが使用している SearchField ではなく、AutoCompleteBox を使用していることに注意してください。

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