XAML ListView - 更改所选项目的图像源

时间:2013-01-27 20:17:05

标签: xaml listview windows-8 windows-runtime

我正在使用带有自定义模板的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中我可以使用Trigger手动更改它。

但是因为在winRT它不再起作用了,我已经研究过VSM了,但我不知道如何才能实现这一点。

有人能为我提供一个真实的例子吗?

谢谢

2 个答案:

答案 0 :(得分: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(发件人为Grid,“Selected2”,true);

  3. 这是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中获得相同的结果,请提供您的解决方案。

    谢谢

答案 1 :(得分:-2)

您可以为ListViewItem创建一个样式,其中包含触发器的controltemplate和数据绑定的datatemplate,如下所示:

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

希望这有用,尊重!