【发布时间】:2019-04-10 10:19:53
【问题描述】:
简而言之,我的问题是:
- 我正在 Windows 通用/UWP 应用中使用
ListView(和DataTemplate)呈现一组不可变项。 - 由于集合中的项目是不可变的,我想避免更改通知代码并使用高效的
{x:Bind Mode=OneTime}默认值。 - 但是,
MyUserControl在其UserControlViewModel绑定之前呈现。调试,我看到set之前有一个属性get。
如何确保在呈现OneTime 之前设置UserControlViewModel?
一个完整的例子如下:
MainPage.xaml
<Page x:Class="MyApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyApp" xmlns:sys="using:System">
<ListView ItemsSource="{x:Bind PageViewModel}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="sys:String">
<local:MyUserControl UserControlViewModel="{x:Bind}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
MainPage.xaml.cs
using Windows.UI.Xaml.Controls;
namespace MyApp {
public sealed partial class MainPage : Page {
public string[] PageViewModel { get; set; } = new string[] { "Item1", "Item2" };
public MainPage() { InitializeComponent(); }
}
}
MyUserControl.xaml
<UserControl x:Class="MyApp.MyUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock Text="{x:Bind ViewModel}" />
</UserControl>
MyUserControl.xaml.cs
using Windows.UI.Xaml.Controls;
namespace MyApp {
public sealed partial class MyUserControl : UserControl {
public string UserControlViewModel { get; set; } = "Default Value";
public MyUserControl() { InitializeComponent(); }
}
}
此代码呈现一个包含两行文本“默认值”的页面;相反,我的意图是显示值“Item1”和“Item2”。
如果我们将PageViewModel 设为空ObservableCollection<string> 并稍后填充它,问题仍然存在。有趣的是,将ListView 替换为ListBox,或完全删除ListView,将set 在get 之前,并按预期呈现:
MainPage.xaml
<Page x:Class="MyApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyApp">
<local:MyUserControl UserControlViewModel="{x:Bind PageViewModel[0]}" />
</Page>
【问题讨论】:
-
旁注:您提到集合是可变的,在您的代码中是一个字符串数组。更改字符串数组的内容(=改变它)不会触发 UI 的更新,因为(字符串)数组无法通知绑定机制。选择具有内置更改通知(例如 ObservableCollection
)的集合类型而不是数组,这将使您能够在绑定 ItemsControl 自动更新其视图的同时改变集合... -
我不知道您所说的“没有 ListView 容器(即单个项目)是什么意思?”。因此,我不确定我是否应该感到惊讶;-)
-
其实,让我收回我的第一条评论。我检查了文档。
x:Bind似乎没有要求绑定目标必须是 DependencyProperty(这似乎仅适用于传统绑定{Binding ...})。很抱歉造成混乱:( -
嗯,文档 (docs.microsoft.com/en-us/windows/uwp/xaml-platform/…) 有点欠缺。当您指定没有路径
{x:Bind}的 x-bind 时,它并没有清楚地说明操作模式是什么。由于无法测试自己(此处没有 Windows 10),我只能猜测问题与未在模板中指定带有{x:Bind}的路径有关。如果您将字符串包装在带有字符串属性的结构中,使用带有这些结构的数组,并让模板中的 {x:Bind} 引用结构字符串属性会发生什么? -
除了我在上一条评论中的建议之外,如果您在数据模板中使用
{x:Bind Path=.}或类似名称会怎样?
标签: c# xaml mvvm data-binding uwp