【问题标题】:WPF Editable ComboBoxWPF 可编辑组合框
【发布时间】:2010-07-30 16:00:39
【问题描述】:

我有一个 ComboBox 并且 ComboBox.IsEditable 属性设置为 True 以使 ComboBox 同时充当 TextBox 和下拉列表。但是当 ComboBox 是数据绑定时,输入自定义文本不会导致将新项目添加到数据绑定集合中。

例如,如果我在绑定到人员列表的 ComboBox 中输入“Joe”,该列表不包含值“Joe”,则不会将值“Joe”添加到 drop - 自动下列表。

处理这个问题的最佳方法是什么?

【问题讨论】:

    标签: wpf


    【解决方案1】:

    这是获得所需行为的基本MVVM 兼容方式:

    MainWindow.xaml

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel>
            <ComboBox Margin="30,5,30,5"
                      IsEditable="True"
                      ItemsSource="{Binding Items}"
                      SelectedItem="{Binding SelectedItem}"
                      Text="{Binding NewItem, UpdateSourceTrigger=LostFocus}"/>
            <TextBox Margin="30,5,30,5" />
        </StackPanel>
    </Window>
    

    MainWindow.cs

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private string _selectedItem;
    
        private ObservableCollection<string> _items = new ObservableCollection<string>()
        {
            "One",
            "Two",
            "Three",
            "Four",
            "Five",
        };
    
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    
        public IEnumerable Items
        {
            get { return _items; }
        }
    
        public string SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                OnPropertyChanged("SelectedItem");
            }
        }
    
        public string NewItem
        {
            set
            {
                if (SelectedItem != null)
                {
                    return;
                }
                if (!string.IsNullOrEmpty(value))
                {
                    _items.Add(value);
                    SelectedItem = value;
                }
            }
        }
    
        protected void OnPropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    我必须在窗口中放置另一个控件,因为我已将Text 绑定的UpdateSourceTrigger 属性设置为LostFocus。如果窗口中没有其他控件,那么Combobox 将永远不会失去焦点。

    我更改了更新模式,因为默认更新模式是Propertychanged,它会为每次击键添加一个新项目。

    例如如果您输入文本“窗口”,则以下内容将添加到您的集合中:

    W
    Wi
    Win
    Wind
    Windo
    Window
    

    【讨论】:

    • 我必须添加一个 get { return SelectedItem; } 到 NewItem 属性让我工作。
    【解决方案2】:

    我会在 LostFocus 事件中处理它。

    这里可以检查 SelectedItem 是否为空。如果是这样,请将 Text 的值添加到绑定列表并将 SelectedItem 设置为新项目。

    在 XAML 中:

      <ComboBox Name="_list" LostFocus="LostFocus" IsEditable="True"/>
    

    在代码隐藏中:

        private ObservableCollection<string> _names;
        public MainWindow()
        {
            InitializeComponent();
            _names = new ObservableCollection<string> {"Eric", "Phillip"};
            _list.SetBinding(ItemsControl.ItemsSourceProperty, new Binding {Source = _names});
        }
    
        private void LostFocus(object sender, RoutedEventArgs e)
        {
            var comboBox = (ComboBox) sender;
            if(comboBox.SelectedItem != null)
                return;
            var newItem = comboBox.Text;
            _names.Add(newItem);
            comboBox.SelectedItem = newItem;
        }
    

    希望这会有所帮助:)

    【讨论】:

    • 您可能还想在 DropDownOpened 事件中执行此操作。
    • 您还应该处理 PreviewKeyDown 并处理 Key.Enter
    【解决方案3】:

    我的建议是使用 MVVM 方法并将 ComboBox.Text 绑定到 ViewModel 的某些 TextProperty。 (同样可以通过在视图中添加一个字符串属性来实现) 然后,您可以处理此属性的设置器中的输入并将该新项目添加到列表中,无论它在视图中以哪种方式“提交”。 AFAIK 没有开箱即用的机制来向您的数据源添加新项目,无论如何您都必须自己进行项目生成。

    或者,您可以同时绑定 - SelectedItem 和 ComboBox 的 Text - 以避免在用户输入已知项目的情况下进行查找。但这部分对于回答您的问题可能不太重要。

    【讨论】:

      猜你喜欢
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多