【问题标题】:How to customize hover behavior of Custom color palette for InkToolbarBallpointPenButton?如何为 InkToolbarBallpointPenButton 自定义自定义调色板的悬停行为?
【发布时间】:2021-11-15 11:10:45
【问题描述】:

我正在使用 InkToolbar 并在其中定义了一个 InkToolbarBallpointPenButton。我在 InkToolbar 资源中为此 InkToolbarBallpointPenButton 定义了一个自定义调色板。但是,当我运行以下代码并将鼠标悬停在此自定义调色板中定义的颜色上时,我可以看到为颜色定义的 rgb 值,而不是颜色的名称。

<InkToolbar
    InitialControls="None">
    <InkToolbar.Resources>
        <BrushCollection x:Key="MyPalette">
              <SolidColorBrush Color="Red" />
              <SolidColorBrush Color="Blue" />
        </BrushCollection>
         </InkToolbar.Resources>
          <InkToolbarBallpointPenButton
               Palette="{StaticResource MyPalette}" />
      </InkToolbar>

如何更改悬停行为以显示颜色名称(例如:蓝色、红色)而不是此处的 RGB 值?

【问题讨论】:

    标签: uwp uwp-xaml


    【解决方案1】:

    当您单击InkToolbarBallpointPenButton 时,它将显示一个InkToolbarPenConfigurationControl,其中显示了您预定义的颜色。您在这些颜色中看到的ToolTip 是由系统控制的,因此我们无法对其进行修改。

    但是有一个解决方法,我们可以在这些颜色上创建自己的ToolTips,以替换这些由系统控制的ToolTips。以下是您需要执行的步骤。

    1. 你需要找到InkToolbarPenConfigurationControl的默认样式,你可以在generic.xaml找到。复制默认样式,放入Application Resources中。

    2. 修改应用程序资源中的InkToolbarPenConfigurationControl 样式。您需要将ToolTip 添加到GridView 项目模板。

    3. 为了显示颜色名称,我们需要创建一个值转换器将SolidColorBrush 转换为颜色名称字符串。这将在ToolTip 中用作颜色名称。

    我这里做了一个示例,你可以参考以下代码:

    Xaml 风格:

       <Application.Resources>
         <!--value converter-->
        <local:ColorConverter x:Key="ColorConverter" />
        <!--style-->
        <Style TargetType="InkToolbarPenConfigurationControl" >
            <Setter Property="IsTabStop" Value="false" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="InkToolbarPenConfigurationControl">
                        <Grid x:Name="RootElement" MinWidth="320">
                            <Grid.ChildrenTransitions>
                                <EntranceThemeTransition />
                            </Grid.ChildrenTransitions>
    
                            <Grid.Resources>
                                <Style x:Key="FlyoutStrokeWidthSelectorStyle" TargetType="Slider">
                                    <Setter Property="IsThumbToolTipEnabled" Value="true" />
                                </Style>
                            </Grid.Resources>
    
                            <Grid.RowDefinitions>
                                <RowDefinition Height="8" />
                                <RowDefinition Height="auto" />
                                <RowDefinition Height="12" />
                                <RowDefinition Height="auto" />
                                <RowDefinition Height="12" />
                                <RowDefinition Height="auto" />
                                <RowDefinition Height="auto" />
                                <RowDefinition Height="auto" />
                                <RowDefinition Height="12" />
                            </Grid.RowDefinitions>
    
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto" />
                            </Grid.ColumnDefinitions>
                            <TextBlock x:Name="PenColorPaletteTitle" Grid.Row="1" Grid.Column="0" Padding="12,0,12,0"
           Style="{ThemeResource BodyTextBlockStyle}" HighContrastAdjustment="None" Text="Colors" />
                            <!-- Color palette -->
                            <!-- Note: ItemsSource and selection are set in code-behind -->
                            <GridView x:Name="PenColorPalette" Grid.Row="3" Grid.Column="0" Padding="4,0,4,2"
    Background="{TemplateBinding Background}" >
                                <GridView.Resources>
                                    <DataTemplate x:Key="HighContrastItemTemplate">
                                        <!-- Keep in sync with the GridView ItemTemplate, down below -->
                                        <Ellipse Margin="8,8,8,8" UseLayoutRounding="false" Fill="{Binding}"
         HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
         Stroke="{ThemeResource InkToolbarFlyoutItemBorderSelectedThemeBrush}"
         StrokeThickness="1"/>
                                    </DataTemplate>
                                </GridView.Resources>
                                <GridView.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="6" />
                                    </ItemsPanelTemplate>
                                </GridView.ItemsPanel>
                                <GridView.ItemContainerStyle>
                                    <Style TargetType="GridViewItem">
                                        <Setter Property="Margin" Value="0" />
                                        <Setter Property="Padding" Value="0" />
                                        <Setter Property="MinHeight" Value="52" />
                                        <Setter Property="MinWidth" Value="52" />
                                        <Setter Property="Height" Value="52" />
                                        <Setter Property="Width" Value="52" />
                                        <Setter Property="HorizontalContentAlignment" Value="Center" />
                                        <Setter Property="VerticalContentAlignment" Value="Center" />
                                        <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="GridViewItem">
                                                    <Grid>
                                                        <!--
                                GridViewItem visual states are documented here:
                                https://msdn.microsoft.com/en-us/library/windows/apps/mt299127.aspx
                            -->
                                                        <VisualStateManager.VisualStateGroups>
                                                            <VisualStateGroup x:Name="CommonStates">
                                                                <VisualState x:Name="Normal" />
                                                                <VisualState x:Name="PointerOver">
                                                                    <VisualState.Setters>
                                                                        <Setter Target="ItemContent.Margin" Value="-2,-2,-2,-2" />
                                                                        <Setter Target="ItemBorder.Margin" Value="2,2,2,2" />
                                                                    </VisualState.Setters>
                                                                </VisualState>
                                                                <VisualState x:Name="Pressed">
                                                                    <VisualState.Setters>
                                                                        <Setter Target="ItemContent.Margin" Value="-2,-2,-2,-2" />
                                                                        <Setter Target="ItemBorder.Stroke" Value="{ThemeResource InkToolbarFlyoutItemBorderPressedThemeBrush}" />
                                                                        <Setter Target="ItemBorder.Margin" Value="2,2,2,2" />
                                                                    </VisualState.Setters>
                                                                </VisualState>
                                                                <VisualState x:Name="Selected">
                                                                    <VisualState.Setters>
                                                                        <Setter Target="ItemContent.Margin" Value="2,2,2,2" />
                                                                        <Setter Target="ItemBorder.Stroke" Value="{ThemeResource InkToolbarFlyoutItemBorderSelectedThemeBrush}" />
                                                                    </VisualState.Setters>
                                                                </VisualState>
                                                            </VisualStateGroup>
                                                            <VisualStateGroup x:Name="FocusStates">
                                                                <VisualState x:Name="Focused" />
                                                                <VisualState x:Name="Unfocused" />
                                                            </VisualStateGroup>
                                                        </VisualStateManager.VisualStateGroups>
                                                        <Ellipse x:Name="ItemBorder"
         Margin="6,6,6,6" UseLayoutRounding="false"
         HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
         Fill="Transparent" Stroke="Transparent" StrokeThickness="2" />
                                                        <ContentPresenter x:Name="ItemContent" UseLayoutRounding="false" />
                                                    </Grid>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </GridView.ItemContainerStyle>
                                <GridView.ItemTemplate>
                                    <DataTemplate>
                                        <!-- Keep in sync with HighContrastItemTemplate item template above -->
                                        <Ellipse Margin="8,8,8,8" UseLayoutRounding="false"
         HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
         Fill="{Binding}" >
                                            <!--our own tooltip-->
                                            <ToolTipService.ToolTip>
                                                <ToolTip Content="{Binding Converter={StaticResource ColorConverter} }" />
                                            </ToolTipService.ToolTip>
                                        </Ellipse>
    
                                    </DataTemplate>
                                </GridView.ItemTemplate>
                            </GridView>
                            <!-- StrokeWidth -->
                            <TextBlock x:Name="PenStrokeWidthTitle" Grid.Row="5" Grid.Column="0" Padding="12,0,12,0"
           VerticalAlignment="Center" Style="{ThemeResource BodyTextBlockStyle}"
           Text="Size" HighContrastAdjustment="None" />
                            <Grid x:Name="StrokePreviewGrid" Grid.Row="6" UseLayoutRounding="false"
      HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
      MinHeight="24">
                                <Canvas x:Name="StrokePreviewCanvas" Margin="12, 0, 12, 4" />
    
                            </Grid>
                            <Slider x:Name="PenStrokeWidthSlider"
        Grid.Row="7" Grid.Column="0" Width="296" Height="44" Margin="12,0,12,0"
        HorizontalAlignment="Stretch"
        Minimum="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PenButton.MinStrokeWidth}"
        Maximum="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PenButton.MaxStrokeWidth}"
        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PenButton.SelectedStrokeWidth, Mode=TwoWay}"
        Style="{StaticResource FlyoutStrokeWidthSelectorStyle}" />
    
                        </Grid>
    
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
    

    值转换器:

     public class ColorConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            SolidColorBrush brush = value as SolidColorBrush;
    
            Color color = brush.Color;
            string selectedcolorname = null;
            foreach (var colorvalue in typeof(Colors).GetRuntimeProperties())
            {
                if ((Color)colorvalue.GetValue(null) == color)
                {
                    selectedcolorname = colorvalue.Name;
                }
            }
    
            return selectedcolorname;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
    

    结果如下所示:

    【讨论】:

    • 这个解决方案效果很好。谢谢!
    • 在 ApplicationResources 而不是页面资源或 GridResources 下定义样式的任何具体原因?
    • 无法直接获取 InkToolbarPenConfigurationControl,唯一的办法就是将样式应用为全局样式。要使样式成为全局样式,您必须将其添加到应用程序资源而不是页面资源中。你可以试着把它放在页面资源中,它不会起作用。
    • 知道了!我注意到上述解决方案适用于深色和浅色模式,但在高对比度下失败。我尝试通过在转换器代码中放置断点进行调试,并注意到它没有达到高对比度。知道为什么会这样吗?
    猜你喜欢
    • 2019-04-07
    • 2018-12-12
    • 2020-10-09
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 2023-03-24
    • 2022-11-01
    相关资源
    最近更新 更多