简单的双向数据绑定到模型的属性不起作用,为了重现该问题,我在 Visual Studio 2013 中创建了一个新项目,即使用带有 .NET 框架 4.5 的空白应用程序(通用应用程序)模板
该模型
namespace UWP.MVVM.Models
{
public class PersonModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
基本视图模型
namespace UWP.MVVM.Core
{
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class VMBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
INavigable 接口
namespace UWP.MVVM.Core
{
#if WINDOWS_PHONE_APP
using Windows.Phone.UI.Input;
#endif
public interface INavigable
{
void Activate(object parameter);
void Deactivate(object parameter);
#if WINDOWS_PHONE_APP
void BackButtonPressed(BackPressedEventArgs e);
#endif
}
}
主视图模型
namespace UWP.MVVM.ViewModels
{
using UWP.MVVM.Core;
using UWP.MVVM.Models;
#if WINDOWS_PHONE_APP
using Windows.Phone.UI.Input;
#endif
public class MainViewModel : VMBase, INavigable
{
private PersonModel person;
public MainViewModel()
{
this.Person = new PersonModel();
}
public PersonModel Person
{
get
{
return this.person;
}
set
{
if (value == this.person)
{
return;
}
this.person = value;
this.NotifyPropertyChanged();
}
}
public void Activate(object parameter)
{
this.Person.FirstName = "Gerrard";
}
public void Deactivate(object parameter)
{
}
#if WINDOWS_PHONE_APP
public void BackButtonPressed(BackPressedEventArgs e)
{
}
#endif
}
}
主页面视图
<Page
x:Class="UWP.MVVM.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP.MVVM"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:UWP.MVVM.ViewModels"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!--<Page.DataContext>
<vm:MainViewModel/>
</Page.DataContext>-->
<Grid Margin="24,24">
<TextBox Header="First Name"
Text="{Binding Person.FirstName}"/>
</Grid>
</Page>
后面的主页代码
namespace UWP.MVVM
{
using UWP.MVVM.Core;
#if WINDOWS_PHONE_APP
using Windows.Phone.UI.Input;
#endif
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using UWP.MVVM.ViewModels;
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
this.DataContext = new MainViewModel();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
navigableViewModel.Activate(e.Parameter);
}
#if WINDOWS_PHONE_APP
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
#endif
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
navigableViewModel.Deactivate(e.Parameter);
}
#if WINDOWS_PHONE_APP
HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
#endif
}
#if WINDOWS_PHONE_APP
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
var navigableViewModel = this.DataContext as INavigable;
if (navigableViewModel != null)
{
navigableViewModel.BackButtonPressed(e);
}
}
#endif
}
}
我尝试在 TextBox 上使用 Mode=TwoWay 并且它不起作用,但是当我在 xaml 中设置 DataContext 而不是后面的代码时,即使没有 Mode=TwoWay 属性,数据绑定也可以工作。
我想在文件后面的代码中设置 DataContext,就像在我遇到这个问题的实际项目中一样,我正在使用 MVVM-light 库及其 SimpleIoc 容器,所以我想从 SimpleIoc 获取视图模型实例并设置DataContext,因为视图模型依赖是由 SimpleIoc 注入的,代码会干净很多。