1

我正在使用带有自定义模板的 ListView,如下所示:

<ListView.ItemTemplate>
    <DataTemplate>
        <Grid HorizontalAlignment="Center" Width="220" Height="220">
            <Image x:Name="image" Stretch="UniformToFill" 
                    Source="{Binding Brand.Image, 
                             ConverterParameter=transparent, 
                             Converter={StaticResource LogoToUriConverter}}"/>
            <StackPanel VerticalAlignment="Bottom">
                <TextBlock Text="{Binding Name}" 
                            Foreground="{StaticResource ApplicationColor}" 
                            Style="{StaticResource TitleTextStyle}" 
                            Height="30" Margin="15,0,15,0"/>
                <TextBlock Text="{Binding Name}" 
                            Foreground="{StaticResource ApplicationColor}" 
                            Style="{StaticResource CaptionTextStyle}" 
                            TextWrapping="NoWrap" Margin="15,0,15,10"/>
            </StackPanel>
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>

现在,选择项目时,我希望将所选项目更改为新的图像源。

Brand.Image 不是 DependencyProperty,因为它来自外部 DataObject。

所以,我认为在 WPF 中我可以使用触发器手动更改它。

但是因为在 winRT 中它不再起作用了,所以我研究了 VSM,但我不知道如何才能做到这一点。

有人可以给我一个真实的例子吗?

谢谢

4

2 回答 2

0

我能够以一种棘手的方式解决这个问题,但我得到了它的工作:

  1. 使用 ExtendedVisualStateManager,(通过 ExpressionBlend dll 可用于 .NET,但不适用于 WinRT,所以我从这里得到它:http: //nroute.codeplex.com/SourceControl/changeset/69480#nRoute5/nRoute.Framework.Metro /Components/ExtendedVisualStateManager.cs )

  2. 有了它,我只需捕获一个 OnSelected 事件并使用新的 VisualStateManager 来执行此操作:

    ExtendedVisualStateManager.GoToElementState(sender as Grid, "Selected2", true);

这是 ItemTemplate 的完整 XAML:

<DataTemplate>
<Grid x:Name="ItemGrid" HorizontalAlignment="Center" Width="220" Height="220" PointerPressed="GridItemTapped">
    <Image x:Name="image" Stretch="UniformToFill" Source="{Binding Brand.Name, ConverterParameter=white, Converter={StaticResource LogoToUriConverter}}"/>
    <Image x:Name="image_colored" Stretch="UniformToFill" Visibility="Collapsed" Source="{Binding Brand.Name, ConverterParameter=colored, Converter={StaticResource LogoToUriConverter}}"/>
    <StackPanel VerticalAlignment="Bottom">
        <TextBlock Text="{Binding Name}" Foreground="White" Style="{StaticResource TitleTextStyle}" Height="30" Margin="15,0,15,0"/>
        <TextBlock Text="{Binding Name}" Foreground="White" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
    </StackPanel>
    <VisualStateManager.CustomVisualStateManager>
        <vsm:ExtendedVisualStateManager/>
    </VisualStateManager.CustomVisualStateManager>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="SelectionStates">
            <VisualState x:Name="Selected2">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="Visibility">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00.0000000">
                            <DiscreteObjectKeyFrame.Value>
                                Collapsed
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image_colored" Storyboard.TargetProperty="Visibility">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00.0000000">
                            <DiscreteObjectKeyFrame.Value>
                                Visible
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

希望这可以帮助任何有同样问题的人。

如果您有更好、更简单的方法在 WinRT 中实现相同的结果,请提出您的解决方案。

谢谢

于 2013-02-01T00:16:49.677 回答
-2

您可以为您的 ListViewItem 创建一个样式,为触发器创建一个控件模板,为您的数据绑定创建一个数据模板,如下所示:

   <Style x:Key="FocusedContainer" TargetType="{x:Type ListViewItem}">
        <EventSetter Event="GotKeyboardFocus" Handler="OnListBoxItemContainerFocused" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Border x:Name="backgroundBorder">
                        <ContentPresenter Content="{TemplateBinding Content}">
                            <ContentPresenter.ContentTemplate>
                                <DataTemplate>
                                     <Grid HorizontalAlignment="Center" Width="220" Height="220">
                                <Image x:Name="image" Stretch="UniformToFill" Source="{Binding Brand.Image, ConverterParameter=transparent, Converter={StaticResource LogoToUriConverter}}"/>
                                <StackPanel VerticalAlignment="Bottom">
                                    <TextBlock Text="{Binding Name}" Foreground="{StaticResource ApplicationColor}" Style="{StaticResource TitleTextStyle}" Height="30" Margin="15,0,15,0"/>
                                    <TextBlock Text="{Binding Name}" Foreground="{StaticResource ApplicationColor}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
                                </StackPanel>
                            </Grid>
                                </DataTemplate>
                            </ContentPresenter.ContentTemplate>
                        </ContentPresenter>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="image" Property="Source" Value="{**Insert your alternate binding here**}"
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

然后像这样配置您的 ListView:

<ListView ItemContainerStyle="{StaticResource FocusedContainer}"/>

您会看到该样式有一个 EventSetter:它的目的是即使您在某个控件内单击(而不是直接在背景上),也可以选择正确的项目。您需要在后面的代码中创建处理程序,只需几行:

    private void OnListBoxItemContainerFocused(object sender, System.Windows.RoutedEventArgs e)
    { (sender as ListViewItem).IsSelected = true; }

希望这有帮助,问候!

于 2013-01-28T02:05:55.920 回答