x:绑定默认为OneTime,当Page的Loading事件触发生成的代码的Initialize函数时,它会使用数据更新目标UI。
我有一个带有ViewModel属性的页面。此ViewModel类为其属性实现INPC。只有在加载页面后,才会异步加载viewModel的数据。因此,在页面初始化和随后生成的代码初始化时,使用x:Bind的UI目标将具有空数据。
由于它是OneTime,除非我手动调用更新(我不会),否则它不应该改变。
那么为什么我的x:Bind UI工作?
以下是一些简化的代码片段。
<Page x:Name="MyPage" x:Class="MyProject.Pages.MyPage">
<Button Command="{x:Bind ViewModel.GoToAnotherPageCommand}">
public sealed partial class MyPage : Page
{
public MyPageViewModel ViewModel { get; set; }
public MyPage()
{
this.InitializeComponent();
}
// called by an event bound to a Frame's Navigated, which all pages use
public void OnNavigatedTo()
{
this.ViewModel = new MyPageViewModel();
}
}
public class MyPageViewModel : INotifyPropertyChanged, INotifyPropertyChanging
{
// GoToAnotherPageCommand is an INPC property and its set in the constructor
答案 0 :(得分:2)
您的命令正常工作的原因是因为OnNavigatedTo
在命令实例化之前将被称为。这意味着在代码尝试设置命令时,ViewModel
已经实例化,不再是null
。
为证明我的观点,首先在以下路径下打开文件(可能是 ARM 或* x64,具体取决于您运行的是哪个平台) -
OBJ / 86 /调试/ MyPage.g.cs
这基本上是代码生成的文件,它连接了页面的所有x:Bind
内容。
现在将断点放在命令设置的位置。就我而言,这是一个名为Set_Windows_UI_Xaml_Controls_Primitives_ButtonBase_Command
的方法。然后将另一个断点放在OnNavigatedTo
。
现在运行应用程序,您将看到首先调用OnNavigatedTo
方法。
如果您的网页NavigationCacheMode
设置为Disabled
,则此行为会使OnNavigatedTo
成为实例化x:Bind
绑定的理想位置,因此页面仅使用内存来创建这些新对象当用户实际导航到它时,而不是在页面构造函数中执行所有操作。
不要在Loaded
的{{1}}事件中执行此操作。因为在命令实例化后会被称为。您可以尝试以下代码来实例化Page
,结果非常不同(您的命令将无效)。
ViewModel
答案 1 :(得分:1)
编译的绑定系统(x:Bind
)非常智能,可以检查初始空值,而不会将它们视为您希望绑定的实际值。它将等待第一个非null值并绑定该值。
这是设计原因,因为绑定到初始空值(几乎)绝不是绑定的意图。
我没有找到这些信息的来源,但我相信这是在2015年详细介绍x:Bind系统的Build talk中。
<强>更新强>
正如Justin在下面的评论和他自己的回答中提到的,如果在绑定操作发生后设置了视图模型,绑定将不起作用。
我相信这是因为绑定在属性链中遇到空引用时会终止,但我没有对此进行测试,所以我可能不正确。