【问题标题】:Customizing selected ListboxItem自定义选定的 ListboxItem
【发布时间】:2014-03-10 11:01:37
【问题描述】:

我有一个带有自定义 ItemContainerStyle 的 ListBox(实际上,我有一个 Telerik 的 RadJumpList,但 afaik 它是从 ListBox 继承的)。每个项目包含一个矩形(平铺)和 2 个字符串。到目前为止,默认情况下它工作正常:当我选择一个项目时,字符串的颜色正在改变,并且矩形具有 const 颜色。

<DataTemplate x:Key="DataTemplate1">
        <Grid Margin="0,0,12,12">
            <Rectangle
                x:Name="SlotTile"
                Width="99" Height="99" Fill="Gray"/>

            <StackPanel Grid.Row="0">
                <TextBlock 
                    FontWeight="Black" 
                    FontSize="{StaticResource PhoneFontSizeSmall}" 
                    Text="{Binding Title, Converter={StaticResource ToUpperConverter}}" />
                <TextBlock 
                    FontFamily="{StaticResource PhoneFontFamilySemiBold}" 
                    FontSize="{StaticResource PhoneFontSizeSmall}" 
                    Text="{Binding Information}" />
            </StackPanel>
        </Grid>
    </DataTemplate>

我现在要做的是自定义选定的项目:瓷砖的颜色应该改变,而字符串的颜色应该是一样的。

我正在尝试使用 VisualStateManager 设置自定义样式,但我不知道如何获取矩形和字符串的颜色。

<Style x:Name="MySlotStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid 
                        Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ColorAnimation
                                            Storyboard.TargetName=""
                                            Storyboard.TargetProperty=""
                                            />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unelected">
                                    <Storyboard>

                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

所以,问题是如何从 Style 中设置 DataTemplate 的属性。

编辑:上传样本:http://1drv.ms/1cJrjZ4

EDIT2:我从复选框中提取(并修改了一点)样式:http://pastebin.com/2JV7d5We 他们正在描述 ControlTemplate 内部的控件。

所以,我计划摆脱 DataTemplate 并将所有内容移至 Style.Template.ControlTemplate。现在,当我尝试创建绑定到新属性(矩形颜色)的模板时,它显示“无法识别成员填充”。

<Style x:Name="TestStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid Margin="0,0,12,12">
                        <VisualStateManager.VisualStateGroups>
                            ****
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Unselected"/>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SlotTile" Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Description" Storyboard.TargetProperty="TextForeground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BlackBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                            <Rectangle
                                x:Name="SlotTile"
                                Width="99" Height="99" 
                                Fill="{TemplateBinding Fill}"/>

                            <TextBlock 
                                x:Name="Description"
                                Foreground="{TepmlateBinding TextForeground}"
                                Text="{Binding Title}" />

                            ****
                        </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

【问题讨论】:

    标签: c# templates windows-phone-7 listbox telerik


    【解决方案1】:

    您应该编辑ItemContainerStyle 样式的副本并将充当容器的网格放入其中。然后您可以编辑VisualState.Selected 故事板并将目标设置为Rectangle,将TargetProperty 设置为Fill

    这是ItemContainerStyle 的 XAML 代码:

    <Style x:Key="ItemContainerCustomStyle" TargetType="ListBoxItem">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver"/>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Unselected"/>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SlotTile">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid Margin="0,0,12,12">
                            <Rectangle
                                x:Name="SlotTile"
                                Width="99" Height="99" />
                            <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    编辑:您甚至可以通过使用默认样式中的 Border 容器元素来简化它。因此,您可以删除 GridRectangle 元素。

    <Style x:Key="ItemContainerCustomStyle" TargetType="ListBoxItem">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Width="99" Height="99" x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver"/>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Unselected"/>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    【讨论】:

    • 感谢您的回答。但是我在矩形/边框的“顶部”也有 2 个字符串,我在哪里可以定义它们以及它们的简化版本的颜色?
    • 如果这2个字符串(TextBlocks?)需要出现在选择时具有背景色的边框之外,只需添加一个围绕Border元素的新容器(例如Grid)。
    • 不是在外面,而是在“顶部”,就像 Wp 瓷砖一样。我想在选择ListItem时控制瓦片本身(样本中的矩形)和两个TextBlock的颜色。所以,我至少有 2 个用于选定状态的自定义变量。
    • 在这种情况下,您只需将它们放在 ItemTemplate 中。顺便说一句,你看过 WP Toolkit HubTile 控件了吗?
    • 据我所知,没有简单的方法可以做到这一点,因为两个模板都位于不同的 XAML 名称范围中。但是您可以通过编程方式执行此操作,请查看这篇文章:blog.jerrynixon.com/2012/09/…
    【解决方案2】:

    您不能按名称设置这些属性吗?

    <ColorAnimation
              Storyboard.TargetName="SlotTile"
              Storyboard.TargetProperty="Fill"
              ...
              />
    

    How to customize the WP7 ListBox Selected Item | Part1

    How to customize the WP7 ListBox Selected Item | Part2

    【讨论】:

    • 不,这没有帮助。如果按照您提到的那样设置它们,我根本看不到任何项目。此外,ControlTemplate 中的 Grid 让我有点困惑。
    猜你喜欢
    • 2010-12-10
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多