数据绑定到更改元素属性

时间:2013-01-30 17:01:17

标签: c# wpf binding

我正在开发一个小型WPF应用程序,其中我有一个组合框,它与后面的代码中的ObservableCollection绑定:

public Molecule CurrentMolecule { get; set; }
public ObservableCollection<string> Formulas { get; set; }

public MainWindow()
{
     CurrentMolecule = new Molecule();
     Formulas = new ObservableCollection<string>(CurrentMolecule.FormulasList.ToList());
     DataContext = this;

     InitializeComponent();
}

<ComboBox x:Name="cmbFormula" ItemsSource="{Binding Path=Formulas}" SelectionChanged="cmbFormula_SelectionChanged"/>

这适用于使用CurrentMolecule.FormulasList填充我的组合框但是如果在某些时候我将CurrentMolecule设置为Molecule的新实例,则数据绑定不再有效。我是否需要实现某种OnPropertyChanged事件,以便无论组合框的内容与CurrentMolecule.FormulasList保持同步?

2 个答案:

答案 0 :(得分:2)

您必须实施INotifyPropertyChanged,然后才会在UI中更新更改。

以下是我对您的代码所做的修改。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private Molecule _CurrentMolecule;

        public Molecule CurrentMolecule
        {
            get
            {
                return _CurrentMolecule;
            }
            set
            {
                _CurrentMolecule = value;
                OnPropertyChanged("CurrentMolecule");
                Formulas =  new ObservableCollection<string>(CurrentMolecule.FormulasList.ToList());
            }
        }

        private ObservableCollection<string> _Formulas;

        public ObservableCollection<string> Formulas
        {
            get { return _Formulas; }
            set
            {
                _Formulas = value;
                OnPropertyChanged("Formulas");
            }
        }

        public MainWindow()
        {
            InitializeComponent();

            CurrentMolecule = new Molecule();
            DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

编辑: 更好的方法是创建ViewModel,然后将其绑定到Window的DataContext。

定义一个名为ViewModel的新类,如下所示。请注意,您可能希望更改命名空间

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    public class ViewModel : INotifyPropertyChanged
    {
        #region Properties
        private Molecule _CurrentMolecule;
        public Molecule CurrentMolecule
        {
            get
            {
                return _CurrentMolecule;
            }
            set
            {
                _CurrentMolecule = value;
                OnPropertyChanged("CurrentMolecule");
                Formulas = new ObservableCollection<string>(CurrentMolecule.FormulasList.ToList());
            }
        }

        private ObservableCollection<string> _Formulas;
        public ObservableCollection<string> Formulas
        {
            get { return _Formulas; }
            set
            {
                _Formulas = value;
                OnPropertyChanged("Formulas");
            }
        }
        #endregion

        #region Constructor
        public ViewModel()
        {
            CurrentMolecule = new Molecule();
        }
        #endregion

        #region INotifyPropertyChanged implementation
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

修改文件后面的MainWindow代码,如下所示

public MainWindow()
{
    InitializeComponent();

    DataContext = new ViewModel();
} 

答案 1 :(得分:0)

您可能缺少WPF控件datacontext基础知识。如果您使用{Binding CurrentMolecule.FormulasList}之类的绑定或父控件,只要交换该项的DataContext,datacontext就会绑定到“CurrentMolecule”,绑定将重置。如果您希望将datacontext绑定到FormulasList,即使父datacontext更改也是如此。您需要将该上下文直接绑定到FormulasList属性,并确保其他父控件不使用CurrentMolecule作为datacontext,即使其实例在ViewModel中发生更改也是如此。