Preferred method for binding in MVVM, Data Template in Resources file or just DataContext in View itself?

后端 未结 2 1567
执笔经年
执笔经年 2021-02-06 02:14

This one has got me stumped as I THOUGHT I looked at everything but I must be missing something. I have went off the traditional MVVM pattern from the MSDN magazine:

h

相关标签:
2条回答
  • 2021-02-06 02:32

    Its important to realize when working with WPF that there are two layers: the data layer (DataContext) and the UI layer (the XAML).

    Bindings are used to pull data from the data layer into the View layer.

    When you write

    <UserControl.DataContext>
        <local:DataBoundMVVMChartViewModel/>
    </UserControl.DataContext>
    

    You are telling WPF that it should create a new instance of DataBoundMVVMChartViewModel and use it for the data layer of that UserControl.

    When you write

    <Label Content="{Binding HelloString}" />
    

    you are telling the Label to look in its data layer (the DataContext) for a property called "HelloString", and use it for the Content property.

    If the property "HelloString" does not exist in the data layer (which it does not unless you set the DataContext like you did with <UserControl.DataContext>), the binding will fail and nothing gets displayed except for a binding error in your output window.

    Your DataTemplate from your ResourceDictionary is something different from the DataContext.

    In fact, a ResourceDictionary is just what it sounds like - a dictionary of resources that WPF can use in the application when needed. But objects in the Dictionary are not by default part of the application's UI itself. Instead, they need to be referenced in some way to be used.

    But back to your DataTemplate

    <DataTemplate DataType="{x:Type vm:DataBoundMVVMChartViewModel}">
        <vw:DataBoundMVVMChart/>
    </DataTemplate>
    

    WPF uses DataTemplates to know how to draw specific types of objects. In your case, this DataTemplate is telling WPF that anytime it needs to draw an object of type DataBoundMVVMChartViewModel, it should do so by using a DataBoundMVVMChart.

    To insert an object into the UI, a Content property is normally used, such as

    MyLabel.Content = new DataBoundMVVMChartViewModel();
    

    or

    <ContentControl Content="{Binding SomeDataboundChartViewModelProperty}" />
    

    I actually started out learning MVVM with the exact same article you linked in your question, and had a lot of trouble figuring it out as well, which lead me to doing a little blogging about WPF/MVVM aimed specifically for beginners like me :)

    If you're interested, I have a few blog articles about WPF/MVVM that may help you understand the technology better.

    • What is this "DataContext" you speak of?

    • A simple MVVM example

    As for your actual question:

    Preferred method for binding in MVVM, Data Template in Resources file or just DataContext in View itself?

    I prefer using a DataTemplate in the .Resources somewhere, as then your UI is not specifically tied with one specific DataContext.

    This is especially important when creating re-usable controls with MVVM. For example, if you have a CalculatorUserControl, and you assigned it a DataContext in the control itself such as with <UserControl.DataContext>, then you could never use that CalculatorUserControl with any other DataContext other than the one that is created when the control is created.

    So typically I set the DataContext for the entire application once at startup, and use DataTemplates to tell WPF how to draw the different ViewModels or Models in my application.

    My entire application exists in the data layer, and the XAML is merely a user-friendly interface to interact with the data layer. (If you want to see a code sample, check out my Simple MVVM Example post)

    0 讨论(0)
  • 2021-02-06 02:36

    If you want to use implicit DataTemplates you have to use the view-model-first approach, you however add a view to your DockPanel without a view-model as its context. If you simply add the respective view-model (to a ContentControl or ItemsControl), the view will be created automatically from the DataTemplate with the view-model as its DataContext.

    e.g.

    <ItemsControl Name="ic"/>
    

    ic.Items.Add(new DataBoundMVVMChartViewModel());
    

    I personally prefer this over view-first (e.g. adding a view which then assigns its own DataContext), because you usually want references to the view-models, the view is only secondary and manipulated indirectly by interacting with the view-model.

    0 讨论(0)
提交回复
热议问题