【问题标题】:How to style a custom control Mouse Over - Hover - MyToolkit.Controls.DataGrid如何为自定义控件设置样式鼠标悬停 - MyToolkit.Controls.DataGrid
【发布时间】:2014-02-21 00:49:12
【问题描述】:

我将这个toolkit 用于 WinRT 并开发一个 Windows 8.1 商业应用程序,它有一个数据网格来显示应用程序的参数。

我的应用程序有黑色背景,当我将鼠标悬停在网格项目上时(在电脑上,而不是在平板电脑上),文本变为黑色。这样用户就无法阅读悬停下的内容。

我能够更改网格背景,试图在任何地方找到 Hover 属性,但没有成功。 这是我改变背景的方式:

<controls:DataGrid Height="Auto"
                       ItemsSource="{Binding Params, Mode=TwoWay}"
                       x:Name="gridParams"
                       Grid.Row="1"
                       View:EventHandlers.Attach="SelectionChanged => SelectionChangedHandler($sender)"

                       DefaultOrderIndex="0">
        <controls:DataGrid.Resources>
            <Style TargetType="controls:DataGrid">
                <Setter Property="Background" Value="Black"/>
            </Style>


        </controls:DataGrid.Resources>....

有人用过这个工具包吗?

任何帮助将不胜感激!

谢谢。

【问题讨论】:

  • 查看 VisualStates。 “PointerOver”一般有一个,可以用来改变控件的样式。
  • @NateDiamond 感谢您的评论,但此对象上没有 PointOver。
  • 有,它只是存储在对象的 XAML 深处。我会添加一个答案,因为对此的解释有点详细。
  • 我的坏人!很抱歉我之前找不到。非常感谢!
  • 别担心!它在源代码中很深,不容易访问(例如,我在 CodePlex 上找不到源代码)。

标签: c# xaml windows-8 winrt-xaml windows-8.1


【解决方案1】:

如果您查看DataGrid Style,您会注意到一件事是DataGrid 的主模板只包含一个NavigationList(工具包自己的控件之一),以及自定义StyleTransparentListBox ,即BasedOn ListBox 样式。

NavigationList 实际上是 ExtendedListBox,另一个自定义控件。

这两个都从ListBox 继承了它们的ItemContainerStyles,因为它们不会覆盖它。

这意味着每个项目实际上都继承了默认的ListBoxItem Style

您会从这个Style 中注意到一件事,它有一堆已定义的VisualStates,包括:

<VisualState x:Name="PointerOver">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
                                       Storyboard.TargetProperty="Background">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPointerOverBackgroundThemeBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                       Storyboard.TargetProperty="Foreground">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPointerOverForegroundThemeBrush}" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

现在,有几种方法可以解决此问题。最简单(但最具侵入性)的方法是覆盖 App.Xaml 中的值,就像这样。

<Application
    ...>
    <Application.Resources>
        <SolidColorBrush x:Key="ListBoxItemPointerOverBackgroundThemeBrush" Color="#21000000" />
        <SolidColorBrush x:Key="ListBoxItemPointerOverForegroundThemeBrush" Color="Green" />
    </Application.Resources>
</Application>

这将改变 all ListBoxes 的画笔,所以它可能不太理想。

下一个解决方案是仅覆盖当前控件的 ListBoxItem 模板。这稍微有点困难,需要更多的代码,但它会是这样的:

<controls:DataGrid
    ...>
    <controls:DataGrid.Template>
        <ControlTemplate TargetType="controls:DataGrid">
            <Grid Background="{TemplateBinding Background}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="0" Background="{StaticResource ListBoxItemDisabledForegroundThemeBrush}" Height="50" x:Name="titles" />
                <controls:NavigationList BorderThickness="0" Grid.Row="1"
                             HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
                             Style="{StaticResource TransparentListBox}" Margin="0" x:Name="list" >
                    <controls:NavigationList.ItemContainerStyle>
                        <Style TargetType="ListBoxItem">
                            <Setter Property="Background" Value="Transparent" />
                            <Setter Property="TabNavigation" Value="Local" />
                            <Setter Property="Padding" Value="8,10" />
                            <Setter Property="HorizontalContentAlignment" Value="Left" />
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="ListBoxItem">
                                        <Border x:Name="LayoutRoot"
                                                Background="{TemplateBinding Background}"
                                                BorderBrush="{TemplateBinding BorderBrush}"
                                                BorderThickness="{TemplateBinding BorderThickness}">
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CommonStates">
                                                    <VisualState x:Name="Normal" />
                                                    <VisualState x:Name="PointerOver">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPointerOverBackgroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPointerOverForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Disabled">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemDisabledForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Pressed">
                                                        <Storyboard>
                                                            <DoubleAnimation Storyboard.TargetName="PressedBackground"
                                                                             Storyboard.TargetProperty="Opacity"
                                                                             To="1"
                                                                             Duration="0" />
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPressedForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                                <VisualStateGroup x:Name="SelectionStates">
                                                    <VisualState x:Name="Unselected" />
                                                    <VisualState x:Name="Selected">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedBackgroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="SelectedUnfocused">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedBackgroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="SelectedDisabled">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedDisabledBackgroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedDisabledForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="SelectedPointerOver">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedPointerOverBackgroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="SelectedPressed">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid"
                                                                                           Storyboard.TargetProperty="Background">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedBackgroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                                           Storyboard.TargetProperty="Foreground">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemSelectedForegroundThemeBrush}" />
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                                <VisualStateGroup x:Name="FocusStates">
                                                    <VisualState x:Name="Focused">
                                                        <Storyboard>
                                                            <DoubleAnimation Storyboard.TargetName="FocusVisualWhite"
                                                                             Storyboard.TargetProperty="Opacity"
                                                                             To="1"
                                                                             Duration="0" />
                                                            <DoubleAnimation Storyboard.TargetName="FocusVisualBlack"
                                                                             Storyboard.TargetProperty="Opacity"
                                                                             To="1"
                                                                             Duration="0" />
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Unfocused" />
                                                    <VisualState x:Name="PointerFocused" />
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                            <Grid x:Name="InnerGrid"
                                                  Background="Transparent">
                                                <Rectangle x:Name="PressedBackground"
                                                           Fill="{ThemeResource ListBoxItemPressedBackgroundThemeBrush}"
                                                           Opacity="0" />
                                                <ContentPresenter x:Name="ContentPresenter"
                                                                  Content="{TemplateBinding Content}"
                                                                  ContentTransitions="{TemplateBinding ContentTransitions}"
                                                                  ContentTemplate="{TemplateBinding ContentTemplate}"
                                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                                  Margin="{TemplateBinding Padding}" />
                                                <Rectangle x:Name="FocusVisualWhite"
                                                           Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
                                                           StrokeEndLineCap="Square"
                                                           StrokeDashArray="1,1"
                                                           Opacity="0"
                                                           StrokeDashOffset=".5" />
                                                <Rectangle x:Name="FocusVisualBlack"
                                                           Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
                                                           StrokeEndLineCap="Square"
                                                           StrokeDashArray="1,1"
                                                           Opacity="0"
                                                           StrokeDashOffset="1.5" />
                                            </Grid>
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </controls:NavigationList.ItemContainerStyle>
                </controls:NavigationList>
            </Grid>
        </ControlTemplate>
    </controls:DataGrid.Template>
</controls:DataGrid>


    </controls:DataGrid.Template>
</controls:DataGrid>

只需将ListBoxItemPointerOverBackgroundThemeBrushListBoxItemPointerOverForegroundThemeBrush 的两个引用替换为您想要的任何新值。

虽然这看起来很麻烦,但您现在可以在悬停时将每个项目的颜色更改为您想要的任何颜色。如果你有一堆这些,你也可以存储自定义的DataGrid Style 并重复使用它。

希望这对编码有所帮助!

【讨论】:

  • 您是否在数据网格中发现错误,我应该直接更改其代码/样式?
  • 不一定是错误,但可能添加一个可覆盖的 ItemStyle 属性会使其更简单。 OP 可以自己完成,但我认为给他一个纯 XAML 答案会更容易,他可以使用一次就忘记。
猜你喜欢
  • 2016-10-19
  • 2016-04-27
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 2019-03-06
  • 2011-04-27
  • 1970-01-01
相关资源
最近更新 更多