7

我想获取 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

4 回答 4

8

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

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

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

UserControl然后在您设置的XAML 中x:NameUserControl将您的属性绑定到以下位置的属性Tag

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

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

</UserControl>

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

于 2014-02-06T09:50:20.570 回答
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>
于 2014-05-21T07:51:23.317 回答
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}"/>

这是处理它的一种方法。

于 2013-09-07T10:01:24.530 回答
0

我在 UWP 中是这样的

<GridView x:Name="abc" ItemsSource="{Binding Path=DataContext.Companies,RelativeSource={RelativeSource Mode=TemplatedParent}}"></GridView>
于 2016-05-12T12:35:34.100 回答