2

データベースから取得したデータをコンボボックスに入力する必要があります。取得される可能性のあるレコードの数は数千に達する可能性があるため、ユーザーがコンボボックスに最初の5文字を​​入力するまでデータベースを呼び出さないことで、リストを制限します。次に、combobox.Items.Filterを使用して、ユーザーが追加の文字を入力すると、リストにデータが入力され、段階的にフィルタリングされます。

問題は、プロセスが元に戻せないことです。ユーザーが000-Test11と入力し、表示されているのは000-Test11と000-Test111であるとします。ユーザーがバックスペースを押すと、コンボボックスは000-Test1に戻り、000-Test12、000-Test13などに加えて上記を表示する必要があります。

コンボボックステキストエディタのテキスト変更イベントのロジックは、MSDNスレッドから適応されています-オートコンプリートコンボボックスの実装-Yiling Lai、Rovi Corporationの回答:http ://social.msdn.microsoft.com/Forums/en-US/wpf/thread /cec1b222-2849-4a54-bcf2-03041efcf304/

これが私たちが抱えている問題を示すためのコードです。

StudyProxyクラス:

    namespace WPFTesting
    {
        public class StudyProxy
        {
            public int StudyID { get; set; }
            public string StudyNumber { get; set; }
            public string Title { get; set; }

            public StudyProxy Init()
            {
                this.Title = this.StudyNumber;
                return this;
            }
        }
    }

xaml:

    <Window x:Class="WPFTesting.SelectStudyScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 Height="300" Width="300" SizeToContent="WidthAndHeight">
        <Grid>
            <DockPanel Height="250" Width="250">
                <ComboBox DockPanel.Dock="Top" VerticalAlignment="Top" Name="comboBox1" 
                      IsEditable="True" IsReadOnly="False" Margin="10"
                      DisplayMemberPath="StudyNumber" SelectedValuePath="StudyID"
                      SelectionChanged="comboBox1_SelectionChanged"/>
                <DataGrid Name="dataGrid1" />
            </DockPanel>
        </Grid>
    </Window>

背後にあるコード:

    using System;
    using System.Windows;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Controls.Primitives;
    using System.Runtime.Serialization;

    namespace WPFTesting
    {
        /// <summary>
        /// Interaction logic for SelectStudyScreen.xaml
        /// </summary>
        public partial class SelectStudyScreen
        {
            private Popup _comboBox1Popup;
            private TextBox _comboBox1Editor;
            private StudyProxy _currentItem;

            public SelectStudyScreen()
            {
                InitializeComponent();

                comboBox1.Loaded += new RoutedEventHandler(comboBox1_Loaded);
            }

            private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (comboBox1.SelectedIndex == -1)
                {
                    dataGrid1.ItemsSource = null;
                }
                else
                {
                    _currentItem = comboBox1.SelectedItem as StudyProxy;
                    List<string> studyIDs = new List<string>(new string[] { comboBox1.SelectedValue.ToString() });
                }
            }

            private void comboBox1_Loaded(object sender, RoutedEventArgs e)
            {
                _comboBox1Popup = comboBox1.Template.FindName("PART_Popup", comboBox1) as Popup;
                _comboBox1Editor = comboBox1.Template.FindName("PART_EditableTextBox", comboBox1) as TextBox;

                if (_comboBox1Editor != null)
                {
                    _comboBox1Editor.KeyDown += new System.Windows.Input.KeyEventHandler(comboBox1Editor_KeyDown);
                    _comboBox1Editor.TextChanged += new TextChangedEventHandler(comboBox1Editor_TextChanged);
                    _comboBox1Editor.PreviewKeyDown += new KeyEventHandler(comboBox1Editor_PreviewKeyDown);
                }
            }

            void comboBox1Editor_PreviewKeyDown(object sender, KeyEventArgs e)
            {
                if (_comboBox1Editor.Text != comboBox1.Text)
                { 
                }
            }

            void comboBox1Editor_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
            {
            }

            private void comboBox1Editor_TextChanged(object sender, TextChangedEventArgs e)
            {
                string text = (sender as TextBox).Text.Trim();
                if (text.Length < 5)
                {
                    _comboBox1Popup.IsOpen = false;
                }
                else if (text.Length == 5)
                {
                    _comboBox1Popup.IsOpen = false;

                    comboBox1.ItemsSource = GetTestData();
                }
                else
                {
                    // Adapted
                    // From: Implimenting AutoComplete combobox - Yiling Lai, Rovi Corporation answer
                    // Link: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/cec1b222-2849-4a54-bcf2-03041efcf304/
                    comboBox1.Items.Filter += a =>
                    {
                        if ((a as StudyProxy).StudyNumber.StartsWith(text, StringComparison.OrdinalIgnoreCase))
                        {
                            return true;
                        }
                        return false;
                    };
                    _comboBox1Popup.IsOpen = true;
                }
            }

            private List<StudyProxy> GetTestData()
            {
                List<StudyProxy> list = new List<StudyProxy>();
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test1" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test11" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test111" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test1111" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test12" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test122" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test1222" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test13" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test133" }.Init());
                list.Add(new StudyProxy() { StudyID = 1, StudyNumber = "000-Test1333" }.Init());

                return list;
            }
        }
    }
4

1 に答える 1

0

これでそこにたどり着けるかもしれません。テキストをバインドしましたが、バックスペースで呼び出されます。

Text="{Binding Path=CBvalue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

私も似たようなことをしていますが、先に進んで 20,000 を超える値をダウンロードしています。テキストボックスと別のリストビューを使用しています。仮想化は 20,000 のすべてで大したことではありません。次に、テキストが変更されたら、フィルタリングする前に DispatcherTimer を使用して 1 秒待機し、入力中にフィルタリングされないようにします。次に、DispatchTimer が BackGroundWorker を呼び出してフィルターを適用し、BackGroundWorker をキャンセルできるようにします。ListView を、LINQ を使用してフィルター処理された List にバインドするだけです。DB へのラウンド トリップは低速です。私のリストは半静的です。

于 2012-05-18T20:21:00.977 に答える