繁体   English   中英

从ViewModel了解数据绑定

[英]Understanding Data Binding from a ViewModel

我是C#/。NET的新手,尤其是绑定,因为这对我来说是一个新概念,我确实了解简单的绑定,如下所示……

<TextBox Name="myTextField" Text="{Binding Path=Text, ElementName=myTextField2}" />
<TextBox Name="myTextField2" Text="{Binding Path=Text, ElementName=myTextField}"/>

但是我对如何从ViewModel做到这一点感到困惑。 我正在观看有关MVVM 的视频 ,该视频帮助我理解了一些难以理解的概念,但是由于未提供任何代码,因此我尝试编写代码以查看实际的演示,但是由于缺少了XAML/Binding部分,演示者没有显示代码的那部分。 您可以在5:05分钟看到所有工作原理。

这是所有代码:

人员类别:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MVVM_BestPractices 
{
    public class Person : INotifyPropertyChanged 
    {
        private string _firstName;
        public string FirstName 
        {
            get { return _firstName; }
            set 
            {
                _firstName = value;
                OnPropertyChanged();
                OnPropertyChanged("FullName");
            }
        }

        private string _lastName;
        public string LastName 
        {
            get { return _lastName; }
            set 
            {
                _lastName = value;
                OnPropertyChanged();
                OnPropertyChanged("FullName");
            }
        }

        public string FullName 
        {
            get { return string.Format("{0} {1}", this.FirstName, this.LastName); }
        }

        public Person() {}

        public Person(string firstName, string lastName) 
        {
            this.FirstName = firstName;
            this.LastName = lastName;
        }

        // INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propertyName = "") 
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ViewModel类:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MVVM_BestPractices {
    public class ViewModel : INotifyPropertyChanged
    {
        Person _model;
        public Person Model 
        {
            get { return _model; }
            set 
            {
                _model = value;
                OnPropertyChanged();
            }
        }

        public ViewModel() 
        {
            Model = new Person("Brian", "Lagunas");
        }

        // INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propertyName = "") 
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}

XAML代码:如您所见,我不知道如何绑定ViewModel中的数据。

<Window x:Class="MVVM_BestPractices.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MVVM_BestPractices"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Grid>
        <TextBox  Width="200" Height="30" Margin="158,57,159,233"/>
        <TextBox  Width="200" Height="30" Margin="158,102,159,188"/>
        <TextBlock Text="{Binding Person, Mode=OneWay}" Width="200" Height="30" Margin="158,148,159,142"/>
    </Grid>
</Window>

有人可以帮助我将数据从ViewModel绑定到textBoxes ,如分钟5:05所示吗?

这将帮助我理解BindingMVVM

如果不观看视频,我会说:

<TextBox  Text={Binding Model.FirstName} ... />
<TextBox  Text={Binding Model.LastName} ... />
<TextBlock Text="{Binding Model.FullName, Mode=OneWay}" ... />

这应该行得通,但这仅是因为您在这里在Model类上实现了INotifyPropertyChanged 您并不总是拥有或想要那样的东西。

旁注:尽量避免将Margin=""用于布局目的。 我知道设计师就是这么做的,但这是一个非常糟糕的做法。

在ViewModel中,您将属性称为Model,而不是Person(Person是您的类型)。 因此,您需要将绑定更改为{Binding Model, Mode=OneWay} 绑定将发生,但是您不会得到想要的结果(我想)。 您要编写的不是Model的值(即Model.ToString()),而是Model的FullName属性的值。 因此非常简单: {Binding Model.FullName, Mode=OneWay}

此外,在一组属性中,您应该首先检查新值是否与旧值不同。

set
{
    if (_firstName == value) return;
    _firstName = value;
    OnPropertyChanged();
    OnPropertyChanged(nameof(FullName)); // And use nameof() like this if you're in C# 6
}

如果已设置DataContext(已拥有),则可以轻松绑定到ViewModel中的Model属性:

<TextBlock Text="{Binding Person, Path=FirstName}"/>

或者您可以省略路径:

<TextBlock Text="{Binding Person.FirstName}"/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM