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

标签 c# wpf combobox

我使用 ComboBox 绑定(bind)到 View 模型的字符串属性。我选择 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>

在后面的代码中:

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
        }

    }

最佳答案

这是我对那个问题的修复:

public class ComboBox : System.Windows.Controls.ComboBox
{
    private bool ignore = false;
    protected override void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        if (!ignore)
        {
            base.OnSelectionChanged(e);
        }
    }

    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        ignore = true;
        try
        {
            base.OnItemsChanged(e);
        }
        finally
        {
            ignore = false;
        }
    }
}

关于c# - 如何禁用 ItemsSource 与 ComboBox 的 Text 属性同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22221199/

相关文章:

WPF:ComboBox DisplayMemberPath 突然不再显示了?

c# - 如何在 MVC Controller 中实现数据访问层

wpf - WPF设计时间数据困惑

wpf - 在 SVG 中旋转形状时保持旋转线性渐变不旋转

c# - 在 C# NET 3.5 中使用组合框属性

delphi - 如何在运行时使用另一个过程中的过程在组合框上设置 onChange 事件?

c# - 如何使用多个过滤器计算数据表?

c# - 如何在 CheckBox 上设置 Checked 和 Enabled 属性?

c# - 添加Mvc服务后单独添加Mvc选项

c# - 访问其他线程wpf中的ui元素