如何为 InkToolbarBallpointPenButton 自定义自定义调色板的悬停行为?
How to customize hover behavior of Custom color palette for InkToolbarBallpointPenButton?
我正在使用 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 值?
当您点击 InkToolbarBallpointPenButton
时,它会显示一个 InkToolbarPenConfigurationControl
显示您预先定义的颜色。您看到的这些颜色ToolTip
是由系统控制的,我们无法修改。
但是有一个解决方法,我们可以在这些颜色上制作我们自己的 ToolTips
来替换这些由系统控制的 ToolTips
。以下是您需要执行的步骤。
您需要找到 InkToolbarPenConfigurationControl
的默认样式,您可以在 generic.xaml
中找到它。复制默认样式,放入Application Resources.
修改应用资源中的InkToolbarPenConfigurationControl
样式。您需要将 ToolTip
添加到 GridView
项模板。
为了显示颜色名称,我们需要创建一个值转换器来将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();
}
}
结果如下所示:
我正在使用 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 值?
当您点击 InkToolbarBallpointPenButton
时,它会显示一个 InkToolbarPenConfigurationControl
显示您预先定义的颜色。您看到的这些颜色ToolTip
是由系统控制的,我们无法修改。
但是有一个解决方法,我们可以在这些颜色上制作我们自己的 ToolTips
来替换这些由系统控制的 ToolTips
。以下是您需要执行的步骤。
您需要找到
InkToolbarPenConfigurationControl
的默认样式,您可以在generic.xaml
中找到它。复制默认样式,放入Application Resources.修改应用资源中的
InkToolbarPenConfigurationControl
样式。您需要将ToolTip
添加到GridView
项模板。为了显示颜色名称,我们需要创建一个值转换器来将
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();
}
}
结果如下所示: