WinRT什么可以代替AncestorType?

时间:2013-09-07 08:41:06

标签: 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>

4 个答案:

答案 0 :(得分:7)

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

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

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

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

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

<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类型的依赖属性,你可以绑定任何东西。

答案 1 :(得分:5)

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

示例,(我已将我的根页面命名为&#39; rootGrid&#39;并通过 DataContext =&#34; {Binding ElementName = rootGrid,Path = DataContext}&#34设置上下文;

<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>

答案 2 :(得分:1)

当你在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}"/>

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

答案 3 :(得分:0)

我在UWP中得到了这个

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