【问题标题】:WinRT What can be instead AncestorType?WinRT 可以用什么来代替 AncestorType?
【发布时间】:2013-09-07 08:41:05
【问题描述】:

我想获取 ListView 项目的计数。 但它使用模板,因此,我需要使用 AncestorType,我有一个在 WPF 中可以正常工作的代码,但在 Windows Store Apps 8 中却没有,因为那里没有 AncestorType,所以我能做些什么呢?如何让这段代码在 winRT 中运行?

这是我的代码:

<ListView ItemsSource="{Binding Users}">
    <ListView.Style>
        <Style TargetType="ListView">
        <Style.Setters>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Border BorderThickness="1" BorderBrush="LightGray">
                            <StackPanel>
                                <ScrollViewer>
                                    <ItemsPresenter />
                                </ScrollViewer>
                                <TextBlock Margin="0,4" FontWeight="Bold">
                                    <Run Text="Count: "/>
                                    <Run Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}}, Path=Items.Count, Mode=OneWay}"/>
                                </TextBlock>
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>                    
        </Style.Setters>
    </Style>
    </ListView.Style>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ListViewItem IsHitTestVisible="False">
                <StackPanel>
                    <facebookControls:ProfilePicture Height="74" Width="74" ProfileId="{Binding FacebookId}" />
                    <TextBlock Text="{Binding UserName}" FontSize="18" HorizontalAlignment="Center" />
                </StackPanel>
            </ListViewItem>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

【问题讨论】:

标签: xaml winrt-xaml


【解决方案1】:

Ed Chapel 发布的答案有一个很大的缺点:

<vm:MyViewModel x:Key="ViewModel" />

导致MyViewModel 将再构造一次。在常见情况下,这是不受欢迎的行为。

顺便说一句,有一个完美的技巧可以绑定到父级的DataContext 而无需重建视图模型。

假设 MyViewModel 有一个名为 TestCommand 的“ICommand”,并且是包含您的 UserControl 的页面的当前 DataContext,则设置页面的 x:Name 并将页面的 DataContext 绑定到使用ElementName 绑定的UserControlTag 属性:

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

    <Grid>
        <controls:MyUserControl Tag={Binding DataContext, ElementName='rootPage'} ... />
    </Grid>

    ...
</Page>

然后在 UserControl 的 XAML 中将 x:Name 设置为 UserControl 并将您的属性绑定到 Tag 中的属性:

<UserControl ...
    x:Name="rootControl">

    <Grid>
        <Button Command={Binding Tag.TestCommand, ElementName='rootControl'} ... />
    </Grid>

</UserControl>

这可能不是最干净的技巧,因为Tag 属性是object 类型的依赖属性,您可以将任何东西绑定到它。

【讨论】:

    【解决方案2】:

    最简单的解决方案是在 Context 中命名任何具有您的视图模型的根容器,然后通过提及元素名称在 ContentControl 中设置控件/容器的 DataContext,您将获得相同的上下文。

    例如,(我将页面的根网格命名为“rootGrid”,并通过 DataContext="{Binding ElementName=rootGrid, Path=DataContext}" 设置上下文)

    <ContentControl Name="contentControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                            >
            <Grid Height="600" 
                  Width="600"
                     DataContext="{Binding ElementName=rootGrid, Path=DataContext}"
                  > 
    
                <Image Height="500" Width="500" 
    
                       Source="{Binding photoUrl}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
            </Grid>
        </ContentControl>
    

    【讨论】:

      【解决方案3】:

      当您在ControlTemplate 中时,您需要一些方法来突破并解决底层DataContext。这取决于您如何定义要绑定的对象。例如,如果您在资源中定义了 ViewModel,则可以像访问 Users 属性一样访问它:

      <UserControl ... >
        <UserControl.Resources>
            <vm:MyViewModel x:Key="ViewModel" />
        </UserControl.Resources>
        ...
          <Grid DataContext="{Binding Source={StaticResource ViewModel}}">
            <ListView ItemsSource="{Binding Users}">
            ...
              <ControlTemplate>
              ...
                <Run Text="{Binding Source={StaticResource ViewModel},
                                    Path=Users.Count}"/>
      

      这是解决这个问题的一种方法。

      【讨论】:

      • 我在 ControlTemplate 中,这就是我想要 AncestorType 的原因,你能告诉我可以做什么吗?
      • 谢谢,只需将 Path 更改为 Users.Count(不需要 Source)...
      【解决方案4】:

      我在 UWP 中是这样理解的

      <GridView x:Name="abc" ItemsSource="{Binding Path=DataContext.Companies,RelativeSource={RelativeSource Mode=TemplatedParent}}"></GridView>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多