【问题标题】:Silverlight Listbox Item StyleSilverlight 列表框项目样式
【发布时间】:2009-09-02 14:34:40
【问题描述】:

如何设置列表框的样式,以使选择的文本颜色与默认视图不同?我以多种方式查看了这一点,因为 ContentPresenter 缺少 Foreground 属性。

列表框的默认控件模板提供了几个可以用来调整高亮颜色的矩形。例如,使用默认样式,一个名为 BGColor3 的矩形调整其不透明度以获得高亮效果。

这是我的控制模板的大部分内容:

<Grid>
    <Rectangle x:Name="BGColor2" Fill="{StaticResource HoverBrush}" Stroke="Black" StrokeThickness="1" Opacity="0"/>
    <Rectangle x:Name="BGColor3" Fill="{StaticResource ListboxHighlightBrush}" StrokeThickness="0" Opacity="0"/>
    <Rectangle x:Name="BGColor" Stroke="Black" StrokeThickness="0" Opacity="0.2" Fill="{TemplateBinding Background}"/>
    <Border Height="20">
        <ContentPresenter HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
    </Border>
    <Rectangle Fill="Blue" Opacity="0.4" x:Name="FocusVisual" Stroke="#BF313131" Margin="1" StrokeThickness="1" StrokeDashArray="1 2" StrokeDashCap="Square" Visibility="Collapsed" />
    <Rectangle x:Name="BorderRect" Stroke="Black" StrokeThickness="1" Opacity="0.3" />
</Grid>

在选择视觉状态中,要点如下:

<VisualStateGroup x:Name="SelectionStates">
    <VisualState x:Name="Unselected"/>
    <VisualState x:Name="Selected">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="BGColor2" Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.8"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
</VisualStateGroup>

显而易见的是,矩形的 BGColor2 正在被修改(不透明度),以便所选项目具有背景。很公平。在情节提要的这一部分中,是否可以访问 ContentPresenter 或其他类似的东西并切换文本前景色?

脚注:与视觉状态转换相比,简单地使用不同的模板不是更简洁吗?

----在给出第一个答案后添加----

使用 TextBlock 几乎 可以解决问题,但有趣的是 SelectedUnfocused 的转换似乎没有被强制执行,也就是说,实施您的解决方案可以完美地工作,直到一个人将鼠标悬停在先前选择的项目然后文本再次变为黑色。

这是我的模板:

<!-- ItemStyle brushes -->
<SolidColorBrush x:Key="BaseColorBrush" Color="White"/>
<SolidColorBrush x:Key="BaseColorBrushFaint" Color="#265B0000"/>
<SolidColorBrush x:Key="ForegroundColorBrush" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="HoverBrush2" Color="#FF808000"/>
<LinearGradientBrush x:Key="HoverBrush"  EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF406DC7" Offset="1"/>
    <GradientStop Color="#FF002C83"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ListboxHighlightBrush" EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF7CA8FF" Offset="1"/>
    <GradientStop Color="#FF376FDC"/>
</LinearGradientBrush>

<SolidColorBrush x:Key="HyperlinkBrush" Color="#FFC8A1A1"/>

<!-- Search Listbox ItemStyle -->
<Style x:Key="ItemStyle" TargetType="ListBoxItem">
    <Setter Property="Padding" Value="4"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="Background" Value="{StaticResource BaseColorBrush}"/>
    <Setter Property="BorderBrush" Value="{StaticResource HoverBrush}"/>
    <Setter Property="Foreground" Value="#FF333333"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="TabNavigation" Value="Local"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="BGColor3" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="BGColor" Storyboard.TargetProperty="(UIElement.Opacity)">
                                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.3"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="00:00:00" Value="White"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(UIElement.Opacity)">
                                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.55"/>
                                    </DoubleAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="BGColor2" Storyboard.TargetProperty="(UIElement.Opacity)">
                                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.9"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="00:00:00" Value="White"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="SelectedUnfocused">
                                <Storyboard>
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="BGColor2" Storyboard.TargetProperty="(UIElement.Opacity)">
                                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.9"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="00:00:00" Value="#FFFFFFFF"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Visibility" Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="00:00:00" Value="White"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused">
                                <Storyboard/>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Rectangle x:Name="BGColor2" Fill="{StaticResource HoverBrush}" Stroke="Black" StrokeThickness="0" Opacity="0"/>
                    <Rectangle x:Name="BGColor3" Fill="{StaticResource ListboxHighlightBrush}" StrokeThickness="0" Opacity="0"/>
                    <Rectangle x:Name="BGColor" Stroke="Black" StrokeThickness="0" Opacity="0.3" Fill="{TemplateBinding Background}"/>
                    <Border Height="20">
                        <TextBlock Canvas.ZIndex="22" x:Name="contentPresenter" Foreground="{TemplateBinding Foreground}"
                            Text="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding 
                            HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" />
                    </Border>
                    <Rectangle  Opacity="0.4" x:Name="FocusVisual" Stroke="#BF313131" Margin="1" StrokeThickness="1" StrokeDashArray="1 2" StrokeDashCap="Square" Visibility="Collapsed" />
                    <Rectangle x:Name="BorderRect" Stroke="Black" StrokeThickness="0" Opacity="0.3" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

还有我对模板的消费:

    <ListBox ItemContainerStyle="{StaticResource ItemStyle}" x:Name="testListBox" />

最后是一些填充列表框的代码:

            List<string> data = new List<string>();
            for (int i = 0; i < 30; i++) { 
                data.Add(DateTime.Now.AddDays(i).ToString("MMMM dd yyyy"));
            }           
            testListBox.ItemsSource = data;         

【问题讨论】:

    标签: silverlight-3.0 listbox coding-style


    【解决方案1】:

    将模板中的 ContentPresenter 更改为具有 Foreground 属性的 ContentControl,您可以使用 TemplateBind。

    【讨论】:

    • 谢谢肖恩,所以即使我使用了 TextBlock,我也能够挂接到前台,但我遇到的问题与 VisualState 变化有关,因此当您将鼠标移出所选项目时它保持白色而不是返回默认值。我通过将 ContentPresenter 替换为 TextBlock 来尝试它,只是想看看这是否有所作为并且仍然遇到问题。
    • 啊,好建议!这比 TextBlock 更好。下次我会用它。
    【解决方案2】:

    我试过你的方案。默认情况下,默认列表项的内容是一个黑色的字符串。列表框项具有您可以设置的前景属性,但我不确定它在模板中的位置。他们为使用前景的字符串做了一些特殊的事情,但没有在模板中公开它。您可能想尝试的一个技巧是,如果您知道您将始终拥有字符串内容,则将 controltemplate 的 contentpresenter 替换为具有前景的文本块。 (要编辑 ListItem 的模板,在 Blend3 中右键单击它,然后转到编辑模板,编辑副本,然后修改新样式}

    <ContentPresenter x:Name="contentPresenter" 
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
    Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}"
    ContentTemplate="{TemplateBinding ContentTemplate}" />
    

    <TextBlock x:Name="contentPresenter" Foreground="{TemplateBinding Foreground}"
    Text="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding 
    HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" />
    

    我为文本和前景添加了 TemplateBinding。您应该能够在视觉状态中操纵前景,以使正确的状态看起来被禁用、选中等。我希望这会有所帮助。

    【讨论】:

    • 我发布了回复 - 我实施了您建议的策略,并且 99% 的时间都有效。也许在这一点上,这更像是一个框架问题——在我粘贴的第二个代码示例中,一切正常,直到有人将鼠标移到列表框中的选定项目上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2011-06-04
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多