在WPF中的DataContext中混淆

时间:2014-07-29 06:50:37

标签: wpf mvvm datacontext

我是WPF和MVMM架构的初学者。 VI遇到了许多链接,这些链接解释了WPF MVMM体系结构中的DataContext依赖属性,

即。 view.DataContext = new ViewModels.MainViewModel();

但是他们总是让我感到困惑。虽然我对这个DataContext有一些基本的想法,比如它用于表示我们在xaml文件中需要的对象,但是当博客讨论dataContext的树结构继承时,我感到困惑。任何人都可以帮我一些非常简单明了的例子来说明DataContext的这种层次结构是如何工作的吗?

先谢谢。

2 个答案:

答案 0 :(得分:2)

DataContext属性指定Data Binding的默认来源。请考虑以下示例:

<TextBox Text="{Binding MyProperty}" />

这个Binding说的是:从MyProperty内的任何对象获取DataContext的值,将其转换为字符串并将其放入TextBox。因此,如果我们将DataContext的{​​{1}}设置为以下类的对象:

TextBox

然后,public class Example { int MyProperty { get { return 3; } } } 的{​​{1}}将设置为Text

价值Inherit是什么意思?考虑一个稍微复杂的例子:

TextBox

如果我们的屏幕上有10个或更多3个元素,那么将<Window Name="MainWindow"> <StackPanel> <TextBox Text="{Binding MyProperty}" /> ...etc 分配给每个TextBox将是一项毫无意义的工作。为了解决这个问题,WPF的实施者决定在我们的案例中设置TextBox上的DataContext也会将其应用于DataContext所有内部(所有子项,所有嵌套元素),直到MainWindow属性被覆盖(即我们设置Window的{​​{1}},然后DataContext及其所有子项也将收到此DataContext {1}})。

如果您希望在行动中看到此行为,同样适用于TextBox媒体资源,请尝试将TextBox的{​​{1}}设置为DataContext,看看会发生什么那里的所有文字!

答案 1 :(得分:1)

Datacontext属性是View的所有绑定的默认源。 在MVVM中,Datacontext用于将ViewModel链接到View。

由于Datacontext属性是依赖属性,如果你不在控件中定义它,它将继承自他的父亲等。

这是 MVVM实现的例子

所有ViewModel类的父级(在所有ViewModel中实现INotifyPropertyChanged):

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

注意:INotifyPropertyChanged允许您的ViewModel通知视图更改(用于绑定)。

让我们说我希望将MainWindows(View)链接到ViewModel:

    public MainWindow()
    {
        InitializeComponent();

        MainViewModel mainViewModel = new MainViewModel(this);
        this.DataContext = mainViewModel;
    }

使用ViewModel:

class MainViewModel : ViewModelBase
{
    #region fields

    private MainWindow mainWindow;

    private string message = "Hello world !";

    #endregion


    #region properties

    public MainWindow MainWindow
    {
        get
        {
            return this.mainWindow;
        }
    }

    public string Message
    {
        get
        {
            return message;
        }
        set
        {
            this.message = value; OnPropertyChanged("Message");
        }
    }

    // ...

    #endregion

    public MainViewModel(MainWindow mainWindow)
    {
        this.mainWindow = mainWindow;
    }
}

所以现在如果我想在我的View(mainwindow)中绑定MainViewModel的属性,我只需要在我的ViewModel中有一个公共属性,并在我的XAML中创建一个绑定。我不必指定源,因为DataContext是默认源。

所以MainWindow.xaml我可以添加:

<TextBox Text="{Binding Message}" />