[英]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
所示吗?
这将帮助我理解Binding
和MVVM
。
如果不观看视频,我会说:
<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.