add OutlineText
This commit is contained in:
1 parent
bb024f5f0b
commit
979b3326a7
28 files changed
+324
-17
No files matched your search
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,236 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using HandyControl.Data;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class OutlineText : FrameworkElement
|
||||
{
|
||||
private FormattedText _formattedText;
|
||||
|
||||
private Geometry _textGeometry;
|
||||
|
||||
static OutlineText()
|
||||
{
|
||||
SnapsToDevicePixelsProperty.OverrideMetadata(typeof(OutlineText), new FrameworkPropertyMetadata(ValueBoxes.TrueBox));
|
||||
UseLayoutRoundingProperty.OverrideMetadata(typeof(OutlineText), new FrameworkPropertyMetadata(ValueBoxes.TrueBox));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
|
||||
"Text", typeof(string), typeof(OutlineText), new FrameworkPropertyMetadata(
|
||||
string.Empty,
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure |
|
||||
FrameworkPropertyMetadataOptions.AffectsRender, OnFormattedTextInvalidated));
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => (string) GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TextAlignmentProperty = DependencyProperty.Register(
|
||||
"TextAlignment", typeof(TextAlignment), typeof(OutlineText),
|
||||
new PropertyMetadata(default(TextAlignment), OnFormattedTextUpdated));
|
||||
|
||||
public TextAlignment TextAlignment
|
||||
{
|
||||
get => (TextAlignment) GetValue(TextAlignmentProperty);
|
||||
set => SetValue(TextAlignmentProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TextTrimmingProperty = DependencyProperty.Register(
|
||||
"TextTrimming", typeof(TextTrimming), typeof(OutlineText),
|
||||
new PropertyMetadata(default(TextTrimming), OnFormattedTextInvalidated));
|
||||
|
||||
public TextTrimming TextTrimming
|
||||
{
|
||||
get => (TextTrimming) GetValue(TextTrimmingProperty);
|
||||
set => SetValue(TextTrimmingProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TextWrappingProperty = DependencyProperty.Register(
|
||||
"TextWrapping", typeof(TextWrapping), typeof(OutlineText),
|
||||
new PropertyMetadata(TextWrapping.NoWrap, OnFormattedTextInvalidated));
|
||||
|
||||
public TextWrapping TextWrapping
|
||||
{
|
||||
get => (TextWrapping) GetValue(TextWrappingProperty);
|
||||
set => SetValue(TextWrappingProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
|
||||
"Fill", typeof(Brush), typeof(OutlineText), new PropertyMetadata(Brushes.Black, OnFormattedTextUpdated));
|
||||
|
||||
public Brush Fill
|
||||
{
|
||||
get => (Brush) GetValue(FillProperty);
|
||||
set => SetValue(FillProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
|
||||
"Stroke", typeof(Brush), typeof(OutlineText), new PropertyMetadata(Brushes.Black, OnFormattedTextUpdated));
|
||||
|
||||
public Brush Stroke
|
||||
{
|
||||
get => (Brush) GetValue(StrokeProperty);
|
||||
set => SetValue(StrokeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
|
||||
"StrokeThickness", typeof(double), typeof(OutlineText), new PropertyMetadata(ValueBoxes.Double0Box, OnFormattedTextUpdated));
|
||||
|
||||
public double StrokeThickness
|
||||
{
|
||||
get => (double) GetValue(StrokeThicknessProperty);
|
||||
set => SetValue(StrokeThicknessProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(
|
||||
typeof(OutlineText),
|
||||
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
|
||||
|
||||
public FontFamily FontFamily
|
||||
{
|
||||
get => (FontFamily)GetValue(FontFamilyProperty);
|
||||
set => SetValue(FontFamilyProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FontSizeProperty = TextElement.FontSizeProperty.AddOwner(
|
||||
typeof(OutlineText),
|
||||
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
|
||||
|
||||
[TypeConverter(typeof(FontSizeConverter))]
|
||||
public double FontSize
|
||||
{
|
||||
get => (double)GetValue(FontSizeProperty);
|
||||
set => SetValue(FontSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FontStretchProperty = TextElement.FontStretchProperty.AddOwner(
|
||||
typeof(OutlineText),
|
||||
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
|
||||
|
||||
public FontStretch FontStretch
|
||||
{
|
||||
get => (FontStretch)GetValue(FontStretchProperty);
|
||||
set => SetValue(FontStretchProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FontStyleProperty = TextElement.FontStyleProperty.AddOwner(
|
||||
typeof(OutlineText),
|
||||
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
|
||||
|
||||
public FontStyle FontStyle
|
||||
{
|
||||
get => (FontStyle)GetValue(FontStyleProperty);
|
||||
set => SetValue(FontStyleProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FontWeightProperty = TextElement.FontWeightProperty.AddOwner(
|
||||
typeof(OutlineText),
|
||||
new FrameworkPropertyMetadata(OnFormattedTextUpdated));
|
||||
|
||||
public FontWeight FontWeight
|
||||
{
|
||||
get => (FontWeight)GetValue(FontWeightProperty);
|
||||
set => SetValue(FontWeightProperty, value);
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
EnsureGeometry();
|
||||
drawingContext.DrawGeometry(Fill, new Pen(Stroke, StrokeThickness), _textGeometry);
|
||||
}
|
||||
|
||||
private void EnsureFormattedText()
|
||||
{
|
||||
if (_formattedText != null || Text == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var source = PresentationSource.FromVisual(this);
|
||||
var dpi = 1.0;
|
||||
if (source?.CompositionTarget != null)
|
||||
{
|
||||
dpi = 96.0 * source.CompositionTarget.TransformToDevice.M11 / 96.0;
|
||||
}
|
||||
|
||||
_formattedText = new FormattedText(
|
||||
Text,
|
||||
CultureInfo.CurrentUICulture,
|
||||
FlowDirection,
|
||||
new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
|
||||
FontSize, Fill, dpi);
|
||||
|
||||
UpdateFormattedText();
|
||||
}
|
||||
|
||||
private void EnsureGeometry()
|
||||
{
|
||||
if (_textGeometry != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureFormattedText();
|
||||
_textGeometry = _formattedText.BuildGeometry(new Point(0, 0));
|
||||
}
|
||||
|
||||
private void UpdateFormattedText()
|
||||
{
|
||||
if (_formattedText == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_formattedText.MaxLineCount = TextWrapping == TextWrapping.NoWrap ? 1 : int.MaxValue;
|
||||
_formattedText.TextAlignment = TextAlignment;
|
||||
_formattedText.Trimming = TextTrimming;
|
||||
|
||||
_formattedText.SetFontSize(FontSize);
|
||||
_formattedText.SetFontStyle(FontStyle);
|
||||
_formattedText.SetFontWeight(FontWeight);
|
||||
_formattedText.SetFontFamily(FontFamily);
|
||||
_formattedText.SetFontStretch(FontStretch);
|
||||
}
|
||||
|
||||
private static void OnFormattedTextUpdated(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var outlinedTextBlock = (OutlineText)d;
|
||||
outlinedTextBlock.UpdateFormattedText();
|
||||
outlinedTextBlock._textGeometry = null;
|
||||
|
||||
outlinedTextBlock.InvalidateMeasure();
|
||||
outlinedTextBlock.InvalidateVisual();
|
||||
}
|
||||
|
||||
private static void OnFormattedTextInvalidated(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var outlinedTextBlock = (OutlineText)d;
|
||||
outlinedTextBlock._formattedText = null;
|
||||
outlinedTextBlock._textGeometry = null;
|
||||
|
||||
outlinedTextBlock.InvalidateMeasure();
|
||||
outlinedTextBlock.InvalidateVisual();
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
EnsureFormattedText();
|
||||
|
||||
// constrain the formatted text according to the available size
|
||||
// the Math.Min call is important - without this constraint (which seems arbitrary, but is the maximum allowable text width), things blow up when availableSize is infinite in both directions
|
||||
// the Math.Max call is to ensure we don't hit zero, which will cause MaxTextHeight to throw
|
||||
_formattedText.MaxTextWidth = Math.Min(3579139, availableSize.Width);
|
||||
_formattedText.MaxTextHeight = Math.Max(0.0001d, availableSize.Height);
|
||||
|
||||
// return the desired size
|
||||
return new Size(_formattedText.Width, _formattedText.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class StackText : FrameworkElement
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
<DocumentationFile>bin\Release\HandyControl.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Controls\AnimationPath.cs" />
|
||||
<Compile Include="Controls\Other\AnimationPath.cs" />
|
||||
<Compile Include="Controls\Attach\BackgroundSwitchElement.cs" />
|
||||
<Compile Include="Controls\Attach\BorderElement.cs" />
|
||||
<Compile Include="Controls\Attach\DataGridAttach.cs" />
|
||||
@@ -46,37 +46,39 @@
|
||||
<Compile Include="Controls\Attach\TitleElement.cs" />
|
||||
<Compile Include="Controls\Button\ContextMenuButton.cs" />
|
||||
<Compile Include="Controls\Button\ContextMenuToggleButton.cs" />
|
||||
<Compile Include="Controls\Carousel.cs" />
|
||||
<Compile Include="Controls\CirclePanel.cs" />
|
||||
<Compile Include="Controls\CircleProgressBar.cs" />
|
||||
<Compile Include="Controls\GifImage.cs" />
|
||||
<Compile Include="Controls\Other\Carousel.cs" />
|
||||
<Compile Include="Controls\Other\CirclePanel.cs" />
|
||||
<Compile Include="Controls\Other\CircleProgressBar.cs" />
|
||||
<Compile Include="Controls\Text\OutlineText.cs" />
|
||||
<Compile Include="Controls\Other\GifImage.cs" />
|
||||
<Compile Include="Controls\Input\SearchBar.cs" />
|
||||
<Compile Include="Controls\Text\StackText.cs" />
|
||||
<Compile Include="Controls\Tag\TagPanel.cs" />
|
||||
<Compile Include="Controls\Tag\Tag.cs" />
|
||||
<Compile Include="Controls\Time\CalendarWithClock.cs" />
|
||||
<Compile Include="Controls\Time\Clock\Clock.cs" />
|
||||
<Compile Include="Controls\Time\Clock\ClockRadioButton.cs" />
|
||||
<Compile Include="Controls\Growl.cs" />
|
||||
<Compile Include="Controls\ImageViewer.cs" />
|
||||
<Compile Include="Controls\Other\Growl.cs" />
|
||||
<Compile Include="Controls\Other\ImageViewer.cs" />
|
||||
<Compile Include="Controls\Input\ComboBox.cs" />
|
||||
<Compile Include="Controls\Input\DatePicker.cs" />
|
||||
<Compile Include="Controls\Input\DateTimePicker.cs" />
|
||||
<Compile Include="Controls\Input\IDataInput.cs" />
|
||||
<Compile Include="Controls\Input\PasswordBox.cs" />
|
||||
<Compile Include="Controls\Input\TextBox.cs" />
|
||||
<Compile Include="Controls\ISingleOpen.cs" />
|
||||
<Compile Include="Controls\Other\ISingleOpen.cs" />
|
||||
<Compile Include="Controls\Input\NumericUpDown.cs" />
|
||||
<Compile Include="Controls\Pagination.cs" />
|
||||
<Compile Include="Controls\Other\Pagination.cs" />
|
||||
<Compile Include="Controls\Attach\IconElement.cs" />
|
||||
<Compile Include="Controls\Slider\CompareSlider.cs" />
|
||||
<Compile Include="Controls\ColorPicker.cs" />
|
||||
<Compile Include="Controls\Other\ColorPicker.cs" />
|
||||
<Compile Include="Controls\Slider\CompareTrack.cs" />
|
||||
<Compile Include="Controls\Slider\PreviewSlider.cs" />
|
||||
<Compile Include="Controls\ScrollViewer.cs" />
|
||||
<Compile Include="Controls\Other\ScrollViewer.cs" />
|
||||
<Compile Include="Controls\Loading\LoadingBase.cs" />
|
||||
<Compile Include="Controls\Loading\LoadingCircle.cs" />
|
||||
<Compile Include="Controls\Loading\LoadingLine.cs" />
|
||||
<Compile Include="Controls\InternalCanvas.cs" />
|
||||
<Compile Include="Controls\Other\InternalCanvas.cs" />
|
||||
<Compile Include="Controls\StepBar\StepBar.cs" />
|
||||
<Compile Include="Controls\StepBar\StepBarItem.cs" />
|
||||
<Compile Include="Data\Args\CancelRoutedEventArgs.cs" />
|
||||
@@ -140,8 +142,8 @@
|
||||
<Compile Include="Controls\Time\TimeBar\SpeTextBlock.cs" />
|
||||
<Compile Include="Controls\Input\TimePicker.cs" />
|
||||
<Compile Include="Controls\Time\TimeBar\TimeBar.cs" />
|
||||
<Compile Include="Controls\TransitioningContentControl.cs" />
|
||||
<Compile Include="Controls\WatermarkTextBox.cs" />
|
||||
<Compile Include="Controls\Other\TransitioningContentControl.cs" />
|
||||
<Compile Include="Controls\Input\WatermarkTextBox.cs" />
|
||||
<Compile Include="Controls\Window\ImageBrowser.cs" />
|
||||
<Compile Include="Controls\Window\PopupWindow.cs" />
|
||||
<Compile Include="Controls\Window\WindowBorderless.cs" />
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
public static readonly string GifImageDemoCtl = nameof(GifImageDemoCtl);
|
||||
|
||||
public static readonly string OutlineTextDemoCtl = nameof(OutlineTextDemoCtl);
|
||||
|
||||
public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl);
|
||||
|
||||
public static readonly string ToggleButtonDemoCtl = nameof(ToggleButtonDemoCtl);
|
||||
|
||||
@@ -30,7 +30,8 @@ var controlList = new List<string>
|
||||
"CalendarWithClockDemoCtl",
|
||||
"SearchBarDemoCtl",
|
||||
"TagDemoCtl",
|
||||
"GifImageDemoCtl"
|
||||
"GifImageDemoCtl",
|
||||
"OutlineTextDemoCtl"
|
||||
};
|
||||
var styleList = new List<string>
|
||||
{
|
||||
|
||||
@@ -129,6 +129,9 @@
|
||||
<Compile Include="UserControl\Controls\DateTimePickerDemoCtl.xaml.cs">
|
||||
<DependentUpon>DateTimePickerDemoCtl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UserControl\Controls\OutlineTextDemoCtl.xaml.cs">
|
||||
<DependentUpon>OutlineTextDemoCtl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UserControl\Controls\GifImageDemoCtl.xaml.cs">
|
||||
<DependentUpon>GifImageDemoCtl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -386,6 +389,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UserControl\Controls\OutlineTextDemoCtl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UserControl\Controls\GifImageDemoCtl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -627,6 +627,15 @@ namespace HandyControlDemo.Properties.Langs {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 轮廓文本 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string OutlineText {
|
||||
get {
|
||||
return ResourceManager.GetString("OutlineText", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 页码条 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -432,4 +432,7 @@
|
||||
<data name="GifImage" xml:space="preserve">
|
||||
<value>GifImage</value>
|
||||
</data>
|
||||
<data name="OutlineText" xml:space="preserve">
|
||||
<value>OutlineText</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -412,4 +412,7 @@
|
||||
<data name="GifImage" xml:space="preserve">
|
||||
<value>Gif图片</value>
|
||||
</data>
|
||||
<data name="OutlineText" xml:space="preserve">
|
||||
<value>轮廓文本</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,16 @@
|
||||
<UserControl x:Class="HandyControlDemo.UserControl.OutlineTextDemoCtl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
|
||||
xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"
|
||||
Background="{DynamicResource RegionBrush}">
|
||||
<controls:TransitioningContentControl>
|
||||
<StackPanel Margin="32" Width="400">
|
||||
<controls:OutlineText Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=20}"/>
|
||||
<controls:OutlineText Margin="0,10,0,0" FontSize="30" Fill="{DynamicResource SuccessBrush}" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=8}"/>
|
||||
<controls:OutlineText Margin="0,10,0,0" FontSize="30" FontStyle="Italic" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=8}"/>
|
||||
<controls:OutlineText Margin="0,10,0,0" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" FontSize="50" StrokeThickness="2" Fill="{DynamicResource DangerBrush}" Stroke="{DynamicResource PrimaryBrush}" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=5}"/>
|
||||
<controls:OutlineText Margin="0,10,0,0" FontSize="80" FontWeight="Bold" StrokeThickness="4" Fill="{DynamicResource PrimaryBrush}" Stroke="{DynamicResource DangerBrush}" Text="{Binding Source={x:Static langs:Lang.Text}, Converter={StaticResource StringRepeatConverter}, ConverterParameter=2}"/>
|
||||
</StackPanel>
|
||||
</controls:TransitioningContentControl>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace HandyControlDemo.UserControl
|
||||
{
|
||||
public partial class OutlineTextDemoCtl
|
||||
{
|
||||
public OutlineTextDemoCtl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,11 @@
|
||||
<Image Source="../../Resources/Img/LeftMainContent/Animation_16x.png"/>
|
||||
</controls:EdgeElement.LeftContent>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Style="{StaticResource ListBoxItemNew}" Tag="{x:Static data:MessageToken.OutlineTextDemoCtl}" Content="{x:Static langs:Lang.OutlineText}">
|
||||
<controls:EdgeElement.LeftContent>
|
||||
<Image Source="../../Resources/Img/LeftMainContent/TextBlock_16x.png"/>
|
||||
</controls:EdgeElement.LeftContent>
|
||||
</ListBoxItem>
|
||||
<ListBoxItem Tag="{x:Static data:MessageToken.CirclePanelDemoCtl}" Content="{x:Static langs:Lang.CirclePanel}">
|
||||
<controls:EdgeElement.LeftContent>
|
||||
<Image Source="../../Resources/Img/LeftMainContent/ColorWheel_16x.png"/>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
## Latest examples
|
||||
|
||||
### OutlineText
|
||||
|
||||

|
||||
|
||||
### Tag
|
||||
|
||||

|
||||
@@ -22,12 +26,12 @@
|
||||
|
||||

|
||||
|
||||
## History publication
|
||||
|
||||
### DataGrid
|
||||
|
||||

|
||||
|
||||
## History publication
|
||||
|
||||
### Now you can switch to dark theme
|
||||
|
||||

|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Reference in new issue
Block a user