XAML 如何从数据模板中绑定到页面上的属性(WinUI3)?

zf2sa74q  于 2023-08-01  发布在  其他
关注(0)|答案(2)|浏览(142)

我试图从DataTemplate中绑定到页面的属性。根据Databinding in Depth文章,每个数据绑定都有一个DataContext。这个DataContext默认为Page本身,并由子元素继承。但是,DataTemplate会覆盖这个DataContext,从而更改该数据模板 * 中所有元素 * 的上下文。
如何从该数据模板 * 中绑定到Page本身 * 上的属性?在下面的示例(已注解)中,我希望将TextBlock Text属性绑定到MyPage.MyName页面上的属性,该属性位于ListViewDataTemplate中。
使用x:Bind是否可以这样做,或者我是否需要使用Binding?我该怎么做?
MyPage.xaml.cs:

public sealed partial class MyPage : Page
{
    // ...
    public string MyName { get; set; }

    // MyCar is a class with a Name and Color property (both strings).
    public ObservableCollection<MyCar> Cars { get; set; }

    // ...
}

字符串
MyPage.xaml:

<StackPanel>
    <!-- The DataContext for the binding here is the Page itself (MyPage). -->
    <TextBlock x:Name="MyNameTextBlock"
               Text="{x:Bind MyName}"></TextBlock>

    <!-- The DataContext for the binding to the ItemsSource is also the Page itself (MyPage) -->
    <ListView x:Name="MyCarsListView"
              ItemsSource="{x:Bind Cars}">
        <ListView.ItemTemplate>
            <!-- The DataTemplate changes the DataContext, overriding the default. -->
            <!-- The new data context is now the specific item in the collection from the ItemsSource property in the ListView. -->
            <DataTemplate x:DataType="models:MyCar">

                <StackPanel>
                    <!-- The DataContext for these two bindings is now the specific Car. -->
                    <TextBlock x:Name="CarNameTextBlock"
                               Text="{x:Bind Name}"></TextBlock>
                    <TextBlock x:Name="CarColorTextBlock"
                               Text="{x:Bind Color}"></TextBlock>

                    <!-- This DOES NOT WORK. I want to refer to the MyName property on MyPage (a different DataContext). -->
                    <TextBlock x:Name="OwnerTextBlock"
                               Text="{x:Bind MyName}"></TextBlock>
                </StackPanel>
            </DataTemplate>

        </ListView.ItemTemplate>
    </ListView>
</StackPanel>


This question似乎也有类似的问题,但在工作解决方案上答案并不清楚。

pod7payv

pod7payv1#

试试这个方法:
1.使用x:Name命名您的页面。

<Page x:Name="RootPage" ...>

字符串
1.使用BindingElementNamePath绑定代码隐藏属性 MyName

<DataTemplate x:DataType="local:MyCar">
    <!-- Doesn't compile.
    <TextBlock Text="{x:Bind MyName, Mode=OneWay}" />
    -->
    <!-- Doesn't compile.
    <TextBlock Text="{x:Bind RootPage.MyName, Mode=OneWay}" />
    -->
    <!-- Compiles but the binding fails and doesn't work.
    <TextBlock Text="{Binding RootPage.MyName}" />
    -->
    <TextBlock Text="{Binding ElementName=RootPage, Path=MyName}" />
</DataTemplate>


因为你使用的是ListView,所以上面的代码可以工作,但是如果你改变主意,想使用ItemsRepeater,它就不能工作了。
ElementName bindings don't work inside ItemsRepeater DataTemplate #560

vuktfyat

vuktfyat2#

一个简单的解决方案是命名页面,然后从绑定中引用它:

<Page x:Name="RootPage" ...>

<TextBlock x:Name="OwnerTextBlock" Text="{x:Bind MyName, ElementName=RootPage}" />

字符串

相关问题