在MVVM数据模板的资源文件或查看本身结合,只是DataContext的首选方法是什么?(Prefe

2019-09-02 06:55发布

这其中有难住我了,因为我以为我看着一切,但我一定是失去了一些东西。 我已经去了从MSDN杂志的传统MVVM模式:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

同时学习MVVM。 不过我通常复制的大部分代码,然后替换它,因为我需要,但今天我想从头开始构建的东西,看到可能有更多的它比我想象的。 MVVM出现时,我所使用的资源字典,而是用的DataContext直接做不绑定的工作。 这个问题最终要找到其他开发者使用建议结合他们发现。

问题的总结是这样的:为什么“的DataTemplate”在资源字典中似乎行不通如下而是直接“的DataContext”的方法,以期就为绑定呢?

难道是因为我做的代码混合身后后面的代码中设置的意见。 或可能是因为别的东西。 看来我的财产,它的实现是在资源字典中设置正确的视图模型,如果我把“DataContext的”直接在视图的XAML,但为什么不呢? 我认为方法的好处是,你可以设置一帮关系的一次。 我很好奇,如果有一些其他的设置需要做才能得到它的工作。 它是在MVVM方法的主要例子好奇他们使用的数据模板但它似乎还有更多的设置起来比我做的得到他们的“绑定”的工作。

哪些没有为我工作:

我试图做一些很基本的东西,在主窗口的XAML,留下我的一些代码出来,使其更简单:

主窗口XAML:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts" x:Class="WPFTesting12_2.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary Source="Resources.xaml"/>
    </Window.Resources>
    <Grid>
        <DockPanel x:Name="dockpanel">
            <Menu DockPanel.Dock="Top" Height="30">
                <MenuItem Header="Charting">
                    <MenuItem Header="MVVMDataBound" x:Name="mnuDataBoundSeriesMVVMCharting" Click="mnuDataBoundSeriesMVVMCharting_OnClick"/>
                </MenuItem>
            </Menu>
            <TextBlock Height="5" Background="Black" DockPanel.Dock="Top" />
            <DockPanel x:Name="dockchildren" DockPanel.Dock="Bottom"/>
        </DockPanel>
    </Grid>
</Window>

主窗口代码背后:

public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();

            this.WindowState = WindowState.Maximized;
        }


        private void mnuDataBoundSeriesMVVMCharting_OnClick(object sender, RoutedEventArgs e)
        {
            View.DataBoundMVVMChart c = new DataBoundMVVMChart();

            dockchildren.Children.Clear();
            dockchildren.Children.Add(c);
        }
    }
}

资源词典:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:vw="clr-namespace:WPFTesting12_2.View"
                    xmlns:vm="clr-namespace:WPFTesting12_2.ViewModel"
                    >
  <DataTemplate DataType="{x:Type vm:DataBoundMVVMChartViewModel}">
    <vw:DataBoundMVVMChart/>
 </DataTemplate>

<Style TargetType="MenuItem">
        <Setter Property="Background" Value="Wheat"/>
    </Style>
    <Style TargetType="Menu">
        <Setter Property="Background" Value="Wheat"/>
    </Style>

</ResourceDictionary>

查看DataBoundMVVMChart.xaml:

<UserControl x:Class="WPFTesting12_2.View.DataBoundMVVMChart"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFTesting12_2.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <ResourceDictionary Source="..\Resources.xaml"/>
    </UserControl.Resources>
    <Grid>
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="TesterContent"/>
            </Menu>
            <Label DockPanel.Dock="Bottom" Width="300" x:Name="label" Height="50" Foreground="Blue" FontSize="24"  Content="{Binding Path=HelloString}"/>
        </DockPanel>
    </Grid>
</UserControl>

视图模型绑定到上方的查看:

namespace WPFTesting12_2.ViewModel
{
    class DataBoundMVVMChartViewModel : INotifyPropertyChanged
    {
        private string _HelloString;

        public string HelloString
        {
            get { return _HelloString; }
            set 
            {
                _HelloString = value;
                RaisePropertyChanged("HelloString");
            }
        }

        public DataBoundMVVMChartViewModel()
        {
            HelloString = "Hello there from the ViewModel";
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

好了,现在的结合将在视图中失败,但还没有颜色的资源进来,所以我想我做错了什么事,但后面的代码将获得产权了。 因此,让我们继续前进:

什么工作:

Magicially如果我只是添加这些四行的观点:

此添加到在顶部的“用户控件”部分的声明:

xmlns:local="clr-namespace:WPFTesting12_2.ViewModel"

然后设置为用户控件的DataContext的一个参考:

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

Answer 1:

数据层(:与WPF工作时,有两层其重要实现DataContext )和UI层(XAML)。

绑定被用来从数据层向视图层中提取数据。

当你写

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

你告诉WPF,它应该创建一个新的实例DataBoundMVVMChartViewModel并使用它为用户控件的数据层。

当你写

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

你说的是标签在数据层(看DataContext )一个名为“HelloString”属性,并使用它的Content属性。

如果属性“HelloString”并不在数据层中存在(这不,除非你设置DataContext像你那样<UserControl.DataContext>绑定操作将失败,并没有显示,除了在输出绑定错误被窗口。

DataTemplate从您ResourceDictionary是一些来自不同DataContext

事实上, ResourceDictionary正是这听起来像-这WPF可以在应用程序需要时使用资源的字典。 但在字典的对象不是应用程序的UI本身的默认部分。 取而代之的是,他们需要以某种方式被引用时使用。

但是,回到你DataTemplate

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

WPF使用的DataTemplates知道如何绘制特定类型的对象。 在你的情况,这DataTemplate告诉WPF它需要借鉴类型的对象,任何时候DataBoundMVVMChartViewModel ,应该用这样做DataBoundMVVMChart

要插入的对象到所述用户界面中,一个Content属性被正常使用,诸如

MyLabel.Content = new DataBoundMVVMChartViewModel();

要么

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

其实,我开始了学习MVVM完全相同的文章 ,你在你的问题联系在一起的,有很多的麻烦想出来的为好,这使我做一个小小的博客有关WPF / MVVM专门为像我这样的初学者,旨在:)

如果你有兴趣,我对WPF / MVVM一些博客文章,可以帮助您了解该技术更好。

  • 这是什么“的DataContext”你说的?

  • 一个简单的例子MVVM

至于你的实际问题:

在MVVM数据模板的资源文件或查看本身结合,只是DataContext的首选方法是什么?

我更喜欢使用DataTemplate.Resources某处,因为那么你的UI并没有特别有一个特定的捆绑DataContext

与MVVM创建可重复使用的控件时,这一点尤其重要。 例如,如果有一个CalculatorUserControl ,你赋予它DataContext在控制本身诸如与<UserControl.DataContext>则不可能使用CalculatorUserControl与任何其他DataContext比当控制是所创建的一个其它创建。

所以通常我设置DataContext为整个应用程序一旦启动,并且使用DataTemplates告诉WPF如何绘制不同ViewModelsModels在我的应用程序。

我的整个应用程序存在于数据层,并且XAML仅仅是一种用户友好界面,以与该数据层进行交互。 (如果你想看到一个代码示例,看看我的简单例子MVVM后)



Answer 2:

如果你想使用隐式DataTemplates你必须使用视图模型,第一种方法,但是你一个视图添加到您的DockPanel没有一个视图模型为背景。 如果您只需添加相应的视图模型(到ContentControlItemsControl ),显示将自动从创建DataTemplate与视图模型作为其DataContext

<ItemsControl Name="ic"/>

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

我个人比较喜欢这种过度视图第一 (例如添加视图,然后分配它自己DataContext ),因为你通常希望将视图模型引用的观点是只有二,通过与视图模型进行交互操作间接。



文章来源: Preferred method for binding in MVVM, Data Template in Resources file or just DataContext in View itself?