【问题标题】:UWP ListView modifycontrols in datatemplate when item is selected选择项目时UWP ListView修改数据模板中的控件
【发布时间】:2017-02-17 10:12:20
【问题描述】:

我有 ListView,它的 DataTemplate ItemTemplate 看起来像这样>

<DataTemplate>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Rectangle Fill="Black"/>
        <TextBlock Text="{Binding Title}"/>
    </Grid>
</DataTemplate>

当 ListView 中的项目被选中时,我希望 Rectangle 的 Fill 值为 Whilte。

对于 WPF,我可以使用触发器,但在 UWP 上,我没有找到任何触发器。

我不想用C#来监听ListView的ItemSelected事件,然后把所有item的颜色改成黑色再把SelectedItem的颜色设置成白色,因为ListView里面的item太多了

【问题讨论】:

    标签: xaml triggers uwp behavior uwp-xaml


    【解决方案1】:

    最简单的方法是自定义ListView.ItemContainerStyle。 你会发现很多有用的细节here

    这个想法是为列表项创建自定义布局。布局将包含左侧的黑色矩形和右侧的模板(文本框)。

    所以基本上,listview 声明变成了(为了清楚起见,删除了一些代码):

    <ListView x:Name="list" SelectionMode="Single">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Data">
                    <TextBlock Text="{x:Bind Title}" />
                </DataTemplate>
            </ListView.ItemTemplate>
    
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                 <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="8" />
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
    
                                    <Rectangle x:Name="sideRect" Fill="Black" />
    
                                    <Grid
                                        x:Name="ContentPresenterGrid"
                                        Margin="0,0,0,0"
                                        Background="Transparent"
                                        Grid.Column="1">
                                        <Grid.RenderTransform>
                                            <TranslateTransform x:Name="ContentPresenterTranslateTransform" />
                                        </Grid.RenderTransform>
                                        <ContentPresenter
                                            x:Name="ContentPresenter"
                                            Margin="{TemplateBinding Padding}"
                                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                            Content="{TemplateBinding Content}"
                                            ContentTemplate="{TemplateBinding ContentTemplate}"
                                            ContentTransitions="{TemplateBinding ContentTransitions}" />
                                    </Grid>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
    

    然后您必须更新视觉状态以将您的矩形颜色设置为每个状态所需的颜色,例如:(为了清晰起见,我删除了一些动画)

    <VisualState x:Name="Selected">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                <DiscreteObjectKeyFrame KeyTime="0" Value="Red" />
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    

    完整代码:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView x:Name="list" SelectionMode="Single">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Data">
                    <TextBlock Text="{x:Bind Title}" />
                </DataTemplate>
            </ListView.ItemTemplate>
    
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                <Grid
                                    x:Name="ContentBorder"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}">
    
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal">
                                                <Storyboard>
                                                    <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="PointerOver">
                                                <Storyboard>
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Pressed">
                                                <Storyboard>
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <PointerDownThemeAnimation TargetName="ContentPresenter" />
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="Selected">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                    </ObjectAnimationUsingKeyFrames>
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Red" />
                                                    </ObjectAnimationUsingKeyFrames>
    
                                                    <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="PointerOverSelected">
                                                <Storyboard>
    
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                    </ObjectAnimationUsingKeyFrames>
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Green" />
                                                    </ObjectAnimationUsingKeyFrames>
    
                                                    <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="PressedSelected">
                                                <Storyboard>
    
    
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                    </ObjectAnimationUsingKeyFrames>
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Yellow" />
                                                    </ObjectAnimationUsingKeyFrames>
    
    
                                                    <PointerDownThemeAnimation TargetName="ContentPresenter" />
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="DisabledStates">
                                            <VisualState x:Name="Enabled" />
                                            <VisualState x:Name="Disabled">
                                                <Storyboard>
                                                    <DoubleAnimation
                                                        Storyboard.TargetName="ContentBorder"
                                                        Storyboard.TargetProperty="Opacity"
                                                        To="{ThemeResource ListViewItemDisabledThemeOpacity}"
                                                        Duration="0" />
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="MultiSelectStates">
                                            <VisualState x:Name="MultiSelectDisabled">
                                                <Storyboard>
    
    
                                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
                                                        <EasingDoubleKeyFrame KeyTime="0:0:0" Value="32" />
                                                        <SplineDoubleKeyFrame
                                                            KeySpline="0.1,0.9,0.2,1"
                                                            KeyTime="0:0:0.333"
                                                            Value="0" />
                                                    </DoubleAnimationUsingKeyFrames>
    
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="MultiSelectEnabled">
                                                <Storyboard>
    
    
                                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
                                                        <EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32" />
                                                        <SplineDoubleKeyFrame
                                                            KeySpline="0.1,0.9,0.2,1"
                                                            KeyTime="0:0:0.333"
                                                            Value="0" />
                                                    </DoubleAnimationUsingKeyFrames>
    
    
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterGrid" Storyboard.TargetProperty="Margin">
                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="32,0,0,0" />
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
    
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="8" />
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
    
                                    <Rectangle x:Name="sideRect" Fill="Black" />
    
    
                                    <Grid
                                        x:Name="ContentPresenterGrid"
                                        Margin="0,0,0,0"
                                        Background="Transparent"
                                        Grid.Column="1">
                                        <Grid.RenderTransform>
                                            <TranslateTransform x:Name="ContentPresenterTranslateTransform" />
                                        </Grid.RenderTransform>
                                        <ContentPresenter
                                            x:Name="ContentPresenter"
                                            Margin="{TemplateBinding Padding}"
                                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                            Content="{TemplateBinding Content}"
                                            ContentTemplate="{TemplateBinding ContentTemplate}"
                                            ContentTransitions="{TemplateBinding ContentTransitions}" />
                                    </Grid>
                                </Grid>
                            </ControlTemplate>
    
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
    </Grid>
    

    【讨论】:

    • 非常感谢!这是我能用的最好的东西。
    【解决方案2】:

    有一个非常简单的方法可以使用 UWP 应用解决这个问题。 如您所知,UWP 应用程序不支持 WPF 应用程序等触发器。 当我遇到这种情况时,我总是更喜欢使用行为。

    您可以在选择项目时使用自定义行为进行监听,并更改模型中某些属性的颜色值。

    例子:

    <Rectangle Fill="{Binding MyColor,Mode=TwoWay}"/>
    

    在您的行为的事件处理程序中,只需更改您的属性的颜色(MyColor)。

    【讨论】:

    • 你能给我举个例子来说明如何监听自定义行为吗?
    猜你喜欢
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多