我是C#/ .NET的新手,特别是对于绑定,因为对我来说这是一个新概念,我确实理解下面的简单绑定......
<TextBox Name="myTextField" Text="{Binding Path=Text, ElementName=myTextField2}" />
<TextBox Name="myTextField2" Text="{Binding Path=Text, ElementName=myTextField}"/>
但是我对如何从ViewModel
感到困惑。我watching a video关于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
。
答案 0 :(得分:3)
不看视频,我会说:
<TextBox Text={Binding Model.FirstName} ... />
<TextBox Text={Binding Model.LastName} ... />
<TextBlock Text="{Binding Model.FullName, Mode=OneWay}" ... />
这应该有效但只是因为你在这里的Model类上实现了INotifyPropertyChanged
。你并不总是拥有或想要那样。
附注:尽量避免使用Margin=""
进行布局。我知道设计师所做的事情,但这是一个非常糟糕的做法。
答案 1 :(得分:2)
在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
}
答案 2 :(得分:1)
如果已设置DataContext(您拥有),则可以直接绑定到ViewModel中的Model属性:
<TextBlock Text="{Binding Person, Path=FirstName}"/>
或者您可以省略路径:
<TextBlock Text="{Binding Person.FirstName}"/>