【问题标题】:Binding constant Collection to ComboBox & SelectedItem to TextBox将常量 Collection 绑定到 ComboBox 和 SelectedItem 到 TextBox
【发布时间】:2018-04-24 21:49:10
【问题描述】:

我是 WPF 中的 MVVM 新手,遇到以下问题。

我尝试拥有的是两个 ComboBox,每个都绑定到与 ItemsSource 相同的 ObservableCollection<TwoProperties> DList 属性并与 SelectedItem 同步,所以我在我的 XAML 中写了这个

<ComboBox ItemsSource="{Binding DList}" DisplayMemberPath="Property1" SelectedItem="{Binding SelectedD}" />
<ComboBox ItemsSource="{Binding DList}" DisplayMemberPath="Property2" SelectedItem="{Binding SelectedD}" />

使用此视图模型

public class ViewModel : INotifyPropertyChanged
{
    private ObservableCollection<TwoProperties> _dList =
        new ObservableCollection<TwoProperties> {
             new TwoProperties(1,"one"),
             new TwoProperties(2,"two")
        };

    public ObservableCollection<TwoProperties> DList
    {
        get { return _dList; }
        set { _dList = value; OnPropertyChanged("DList"); }
    }

    private TwoProperties _selectedD;
    public TwoProperties SelectedD
    {
        get { return _selectedD; }
        set { _selectedD = value; OnPropertyChanged("SelectedD"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

在哪里

public class TwoProperties
{
    public double Property1 { get; set; }
    public string Property2 { get; set; }

    public TwoProperties (double p1, string p2)
    {
        Property1 = p1;
        Property2 = p2;
    }
}

我还希望有两个文本框来显示同步组合框的当前SelectedItem 的属性。 SelectedD 的属性 Property1Property2 应该是可编辑,但是 ObservableCollection&lt;TwoProperties&gt; _dList 应该保持不变/只读,并且不会更改其值。

<TextBox Text="{Binding SelectedD.Property1}" />
<TextBox Text="{Binding SelectedD.Property2}" />

但是当我编辑 TextBoxes 并因此编辑 SelectedD 时,_dList 也会更改其值,这不是我想要的。

我希望我能解释我的问题。我确定我在这里遗漏了一些简单的东西。

【问题讨论】:

    标签: c# wpf mvvm data-binding combobox


    【解决方案1】:

    这可以通过将 TextBoxes 的绑定模式更改为以下一种方式来轻松实现:

        <TextBox Text="{Binding SelectedD.Property1,Mode=OneWay}" />
        <TextBox Text="{Binding SelectedD.Property2,Mode=OneWay}" />
    

    因此,当您更改 textBox 值时,更改不会反映回 Observable 集合对象。

    请注意,您可以通过修改以下方法来摆脱视图模型 OnPropertyChanged 中的神奇字符串:

    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    

    然后您可以在视图模型内的任何属性的 setter 中调用它,而无需传递属性名称,如下所示:

        private TwoProperties _selectedD;
        public TwoProperties SelectedD
        {
            get { return _selectedD; }
            set { _selectedD = value; OnPropertyChanged(); }
        }
    

    编辑 2: 更新我的绑定和视图模型以获取视图模型中的编辑值

    查看模型更新:

    private double? editPropertyOne;
        public double? EditPropertyOne
        {
            get { return editPropertyOne; }
            set
            {
                editPropertyOne = value;
                OnPropertyChanged();
            }
        }
    
        private string editPropertyTwo;
        public string EditPropertyTwo
        {
            get { return editPropertyTwo; }
            set
            {
                editPropertyTwo = value;
                OnPropertyChanged();
            }
        }
    
        private TwoProperties _selectedD;
        public TwoProperties SelectedD
        {
            get { return _selectedD; }
            set
            {
                _selectedD = value; OnPropertyChanged();
                if (_selectedD != null)
                {
                    EditPropertyOne = _selectedD.Property1;
                    EditPropertyTwo = _selectedD.Property2;
                }
            }
        }
    

    Xaml 更改:

        <TextBox Text="{Binding EditPropertyOne}" />
        <TextBox Text="{Binding EditPropertyTwo}" />
    

    【讨论】:

    • 太好了,谢谢!但是,TextBoxes 中的更改不会反映在 Model=OneWay 的视图模型的属性中,对吧?我想在 selectedD 之类的属性中使用 TextBox 的编辑信息。还是我必须在 ViewModel 中创建一个新属性,每次选择更改时,该属性都会分配并更新到 ComboBox 中的 SelectedD 并将其绑定到 TextBox?
    • 是的,正如您所提到的,如果您想使用编辑后的值,那么您必须在视图模型中创建新属性并在每次选择更改时更新它(请参阅我的第二次编辑答案)
    • 您的解决方案效果很好。现在,由于我的真实类 TwoProperties 不仅有两个属性,而且有 72 个属性,而且我不愿意在我的视图模型中为我的真实类中的每个字段/属性对编写一个字段/属性对,我试图更改它并将两个 EditPropertyOne和 EditPropertyTwo 字段/属性对通过具有 private TwoProperties editProperty;public TwoProperties { get ... set ...} 合二为一。但是,我的 _dList 会被 TextBoxes 中的每一次更改覆盖......现在我假设我必须在 TwoProperties 类中实现INotifyPropertyChanged
    • 如果你打算在一个地方使用 TwoProperties 和与之相关的 UI,那么这将是一个可接受的解决方案,但是如果这种具有相同视图模型类和 UI 的场景在许多地方都存在您的应用程序,那么我建议创建自定义控件或用户控件并封装您的逻辑和数据
    猜你喜欢
    • 2019-06-03
    • 2019-12-05
    • 2014-10-10
    • 2010-10-24
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多