c# – 在MVVM中绑定的首选方法,资源文件中的数据模板或View中的DataContext?

前端之家收集整理的这篇文章主要介绍了c# – 在MVVM中绑定的首选方法,资源文件中的数据模板或View中的DataContext?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这个我已经把我弄糟了,因为我看着一切,但我一定是缺少一些东西.我已经从MSDN杂志中删除了传统的MVVM模式:

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

同时学习MVVM.然而,我通常会复制大部分代码,然后根据需要进行替换,但是今天我想从头开始构建一些东西,并且看到可能比我想象的更多.当我使用资源字典时,MVVM似乎不能与绑定一起使用,而是直接使用数据标签.这个问题最终要找到其他开发者建议使用绑定他们找到的.

问题的总结是这样的:为什么“资源字典”中的“DataTemplate”看起来不会显示在下面,但直接的“DataContext”方法会立即使用视图进行绑定?

是因为我在代码背后的设置视图中混合了代码.或者可能因为别的东西.看来我的属性,如果我在View的XAML中直接设置’DataContext’,那么在viewmodel中设置正确,但为什么不在资源字典?我认为这种方法的优点是您可以一次性设置一堆关系.如果有其他一些设置需要做,让我很好奇,让它好好工作.在他们使用数据模板的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>

viewmodel绑定到上面的视图:

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));
        }
    }
}

好的,现在绑定会在视图中失败,但是颜色的资源会进来.所以我以为我做错了,但后面的代码会立即获得该属性.那我们继续吧

什么工作:

如果我将这四行添加到视图中,就是魔术般的:

将其添加到顶部的“UserControl”段中的声明:

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

然后设置对UserControl的DataContext的引用:

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

解决方法

在使用WPF时,要实现两层:数据层(DataContext)和UI层(XAML)的重要性.

绑定用于将数据从数据层拉入View层.

当你写

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

您正在告诉WPF它应该创建一个新的DataBoundMVVMhartviewmodel实例,并将其用于该UserControl的数据层.

当你写

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

你告诉Label来查找一个名为“HelloString”的属性的数据层(DataContext),并将其用于Content属性.

如果属性“HelloString”不存在于数据层中(除非您使用&UserControl.DataContext>进行设置DataContext),否则绑定将失败,除了您的输出窗口.

您的ResourceDictionary的DataTemplate与DataContext不同.

事实上,一个ResourceDictionary就是它的声音 – WPF可以在需要时在应用程序中使用的资源字典.但是Dictionary中的对象不是应用程序UI本身的默认部分.相反,它们需要以某种方式引用才能使用.

但是回到你的DataTemplate

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

WPF使用DataTemplates来了解如何绘制特定类型的对象.在你的情况下,这个DataTemplate告诉WPF,任何时候它需要绘制一个DataBoundMVVHHhHMWViewviewmodel类型的对象,它应该通过使用DataBoundMVVMhart来实现.

要将对象插入到UI中,通常会使用Content属性,例如

MyLabel.Content = new DataBoundMVVMChartviewmodel();

要么

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

我实际上开始学习MVVM,与您在问题中链接的完全相同的article,并且遇到了很多麻烦,这导致我做一个关于WPF / MVVM的博客,专门针对像我这样的初学者:)

如果您有兴趣,我有一些关于WPF / MVVM的博客文章,可能会帮助您更好地了解技术.

> What is this “DataContext” you speak of?
> A simple MVVM example

至于你的实际问题:

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

我更喜欢在.Resources的某个地方使用DataTemplate,因为你的UI并不是特定的DataContext.

当使用MVVM创建可重用的控件时,这尤其重要.例如,如果您有一个CalculatorUserControl,并且在控件本身中分配了一个DataContext,例如< UserControl.DataContext>,那么您不能将该CalculatorUserControl与除控件之外创建的其他DataContext一起使用被创建.

所以通常我在启动时为整个应用程序设置DataContext一次,并使用DataTemplates来告诉WPF如何在我的应用程序中绘制不同的viewmodels或Models.

我的整个应用程序存在于数据层中,XAML只是一个用户友好的界面来与数据层进行交互. (如果您想查看代码示例,请查看我的Simple MVVM Example文章)

原文链接:https://www.f2er.com/csharp/95815.html

猜你在找的C#相关文章