我想得到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)
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:Name到UserControl,你的属性绑定到一个属性Tag:
<UserControl ...
x:Name="rootControl">
<Grid>
<Button Command={Binding Tag.TestCommand, ElementName='rootControl'} ... />
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
这可能不是最干净的技巧,因为Tag属性是类型的依赖属性,object你可以绑定任何东西.
最简单的解决方案是命名任何在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)
当你身处困境时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)
这是解决这个问题的一种方法。