C# UWP-x:绑定和绑定-FlipView内部AdaptiveGridView-仅使用x:绑定
对.NET生态系统来说是新的 以下代码在空白UWP应用程序中跟踪MVVM时运行良好C# UWP-x:绑定和绑定-FlipView内部AdaptiveGridView-仅使用x:绑定,c#,mvvm,uwp,binding,datatemplate,C#,Mvvm,Uwp,Binding,Datatemplate,对.NET生态系统来说是新的 以下代码在空白UWP应用程序中跟踪MVVM时运行良好 <Page x:Class="UWP.Blank.Mvvm.App01.Views.PrincipalPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2
<Page
x:Class="UWP.Blank.Mvvm.App01.Views.PrincipalPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP.Blank.Mvvm.App01"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:md="using:UWP.Blank.Mvvm.App01.Models"
xmlns:vm="using:UWP.Blank.Mvvm.App01.ViewModels"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
x:Name="ThisPrincipalPage">
<Page.Resources>
<DataTemplate x:Name="FlipView_ItemTemplate" x:DataType="md:MyFlipViewItem">
<Grid>
<Image Source="{x:Bind ImageLocation}" Stretch="Uniform" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AdaptativeGridView_ItemTemplate">
<Grid
Background="White"
BorderBrush="Black"
BorderThickness="1">
<FlipView Width="300" Height="300"
ItemTemplate="{StaticResource FlipView_ItemTemplate}"
ItemsSource="{Binding ElementName=ThisPrincipalPage, Path=ViewModel.FlipViewData}"/>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<controls:AdaptiveGridView x:Name="AdapGridView1"
ItemsSource="{x:Bind Path=ViewModel.AdaptativeGridViewData}"
ItemTemplate="{StaticResource AdaptativeGridView_ItemTemplate}"/>
</Grid>
</Page>
ViewModel是此类的一个实例:
public class PrincipalViewModel
{
public ObservableCollection<int> AdaptativeGridViewData { get; set; } = new ObservableCollection<int>() { 1, 2, 3, 4 };
public ObservableCollection<MyFlipViewItem> FlipViewData { get; set; } = new ObservableCollection<MyFlipViewItem>();
...
}
公共类PrincipalViewModel
{
public observeCollection adaptiveGridViewData{get;set;}=new observeCollection(){1,2,3,4};
public ObservableCollection FlipViewData{get;set;}=new ObservableCollection();
...
}
这提供了两个列表,一个用于AdaptiveGridView控件,另一个用于其中的所有FlipView
我的问题是,有没有办法只使用x:Bind?基本上,因为它声称速度更快。如果这是不可能的,那么x:Bind并不能代替Binding,这会让一切变得更加混乱
我尝试了两个基本的“直观选项”,但都不起作用
选项1,其中FlipView的ItemsSource属性更改为使用x:Bind。错误声明:
绑定路径“ViewModel.FlipViewData”无效:在类型“DataTemplate”上找不到属性“ViewModel”
FlipView的DataTemplate的DataContext似乎与预期不同。可能DataContext指向ViewModel.AdaptiveGridViewData,但是谁知道呢?它是XAML。这是我觉得XAML不方便的原因之一,因为它的行为就像一个“黑匣子”。你知道怎么做,否则你就有麻烦了
在本例中,我尝试使用带有“FindAncestor”实用程序的经典绑定来指向ViewModel。然而,在UWP中,没有实现AncestorType
(即,类似-->ItemsSource=“{Binding FlipViewData,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type AdaptiveGridView}}”)
我很好奇,因为我没有在DataTemplate中明确设置x:DataType。那么,为什么DataContext与AdaptiveGridView或页面中的任何“正常”控件不同呢
选项2,它明确地设置了DataTemplate的x:DataType(注意,这确实在另一个DataTemplate“FlipView\u ItemTemplate”中起作用)。但是,对于“AdaptiveGridView_ItemTemplate”,存在运行时错误
引发异常:UWP.Blank.Mvvm.App01.exe中的“System.InvalidCastException”
没有更多的线索
<DataTemplate x:Key="AdaptativeGridView_ItemTemplate" x:DataType="vm:PrincipalViewModel">
<Grid
Background="White"
BorderBrush="Black"
BorderThickness="1">
<FlipView Width="300" Height="300"
ItemTemplate="{StaticResource FlipView_ItemTemplate}"
ItemsSource="{x:Bind FlipViewData}"/>
</Grid>
</DataTemplate>
欢迎您提供任何经验或建议。您的数据类型必须与数据模板显示的类型相匹配,在本例中,AdaptiveGridView\u ItemTemplate的数据类型为INT。ItemTemplate的DataContext是该模板显示的单个项目的数据上下文,而不是父/ItemsControl的DataContext。在控件为您膨胀/创建DataTemplate实例的任何地方都会出现这种行为。@JohnnyWestlake感谢您分享您的评论!与您的注释相关:因此DataTemplate不能具有任意类型,但必须具有“collection behind”(在ItemsSource中设置)元素的类型。如果是这样,为什么存在要配置的属性x:DataType?x:DataType允许您在数据模板内使用x:Bind(通过允许编译器知道目标类型是什么,从而允许它生成正确的代码),否则只能使用传统绑定。大多数以x:开头的属性通常会触发特殊的编译器逻辑,包括公共x:名称(它创建了允许您从codebehind访问命名XAML元素的代码)@JohnnyWestlake谢谢您的评论。因此,这将回答为什么选项1不起作用,因为没有指定x:DataType。不过,这并不能解释为什么在DataTemplate中使用x:DataType(以及内部使用x:Bind)会产生运行时错误。这是因为您指定的类型与要绑定的类型也不匹配。为X:Bind生成的代码隐藏将尝试将数据模板中显示的项转换为X:DataType中指定的类型。在您的例子中,它将尝试将int转换为PrincipalViewModel,这将抛出您看到的InvalidCastException。(与绑定不同,绑定是动态的,使用反射来访问对象,X:Bind在编译时创建代码来手动同步属性,而不使用反射,因此它需要知道执行正确强制转换的确切类型)
<DataTemplate x:Key="AdaptativeGridView_ItemTemplate">
<Grid
Background="White"
BorderBrush="Black"
BorderThickness="1">
<FlipView Width="300" Height="300"
ItemTemplate="{StaticResource FlipView_ItemTemplate}"
ItemsSource="{x:Bind Path=ViewModel.FlipViewData}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AdaptativeGridView_ItemTemplate" x:DataType="vm:PrincipalViewModel">
<Grid
Background="White"
BorderBrush="Black"
BorderThickness="1">
<FlipView Width="300" Height="300"
ItemTemplate="{StaticResource FlipView_ItemTemplate}"
ItemsSource="{x:Bind FlipViewData}"/>
</Grid>
</DataTemplate>