如何禁用 ItemsSource 与 ComboBox 的 Text 属性同步

use*_*366 5 c# wpf combobox

我使用 ComboBox 绑定到视图模型的字符串属性。我选择 ComboBox 而不是 TextBox,因为我希望有一个从列表中进行选择的选项(作为建议),但我不想在 ItemsSource 更改时更改所选文本。

我尝试将IsSynchronizedWithCurrentItem属性设置为 false,但是当建议列表更改(在所选文本的位置)时,文本更改为空。看来 ComboBox 已经记住了输入的文本也在列表中,并且当该项目消失时, Text 属性也被清除。

所以我的问题是:这是一个错误,还是我做错了什么?如果这是一个错误,您能建议一些解决方法吗?

我创建了一个示例项目来预生成:

在 XAML 中:

<Window x:Class="TestProject1.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">
    <Grid>
        <ComboBox IsSynchronizedWithCurrentItem="False" ItemsSource="{Binding Items}"
                  IsEditable="True" Text="{Binding SelectedText, UpdateSourceTrigger=PropertyChanged}"
                  HorizontalAlignment="Left" Margin="10,39,0,0" VerticalAlignment="Top" Width="120"/>
        <Button Click="Button_Click" Content="Update list" 
                HorizontalAlignment="Left" Margin="10,82,0,0" VerticalAlignment="Top" Width="75"/>
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

在后面的代码中:

public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow() {
            InitializeComponent();

            this.DataContext = this;
            Items = new List<string>() { "0", "1", "2" };
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private List<string> _items;
        public List<string> Items {// I use IEnumerable<string> with LINQ, but the effect is the same
            get { return _items; }
            set {
                if (_items != value) {
                    _items = value;
                    RaisePropertyChanged("Items");
                }
            }
        }

        private string _selectedText;
        public string SelectedText {
            get { return _selectedText; }
            set {
                if (_selectedText != value) {
                    _selectedText = value;
                    RaisePropertyChanged("SelectedText");
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            var changed = Items.ToList();//clone
            int index = changed.IndexOf(SelectedText);
            if (index >= 0) {
                changed[index] += "a";//just change the currently selected value
            }
            Items = changed;//update with new list
        }

    }
Run Code Online (Sandbox Code Playgroud)

Mas*_*ton 0

更改 ItemsSource 后,引发所选文本上已更改的属性以刷新 UI。

因此,在您的 Items 集合设置器中进行更改:

RaisePropertyChanged("Items");
RaisePropertyChanged("SelectedText");
Run Code Online (Sandbox Code Playgroud)

编辑:在您的示例中,您不仅更改了 ItemSource,还更改了当前所选项目的文本,但在旧文本上有文本绑定。你期待看到/发生什么?您是否希望所选项目保持不变,即使其文本发生变化?