C# UWP-x:绑定和绑定-FlipView内部AdaptiveGridView-仅使用x:绑定

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

对.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/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>