WinRT什么可以代替AncestorType?

Mis*_*sky 7 xaml winrt-xaml

我想得到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>
Run Code Online (Sandbox Code Playgroud)

Ale*_*yov 7

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

<vm:MyViewModel x:Key="ViewModel" />
Run Code Online (Sandbox Code Playgroud)

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

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

假设MyViewModel有一个名为TestCommand的'ICommand'并且是DataContext包含你的页面的当前页面,UserControl设置x:Name页面并将页面绑定DataContext到使用绑定的Tag属性:UserControlElementName

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

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

    ...
</Page>
Run Code Online (Sandbox Code Playgroud)

然后在XAML您的UserControl设定的x:NameUserControl,你的属性绑定到一个属性Tag:

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

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

</UserControl>
Run Code Online (Sandbox Code Playgroud)

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


Khu*_*ram 5

最简单的解决方案是命名任何在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>
Run Code Online (Sandbox Code Playgroud)


Ed *_*pel 1

当你身处困境时ControlTemplate,你需要某种方式来突破并解决根本问题DataContext。这取决于您如何定义要绑定的对象。例如,如果您ViewModel在资源中定义了 a,则可以像访问属性一样访问它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}"/>
Run Code Online (Sandbox Code Playgroud)

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