-
Notifications
You must be signed in to change notification settings - Fork 255
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1.add in Badge Adorner 2.add Badge example
- Loading branch information
1 parent
fbbbf78
commit 3eda2b4
Showing
3 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
src/WPFDevelopers.Samples.Shared/ExampleViews/BadgeExample.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<UserControl | ||
x:Class="WPFDevelopers.Samples.ExampleViews.BadgeExample" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers" | ||
d:DesignHeight="450" | ||
d:DesignWidth="800" | ||
mc:Ignorable="d"> | ||
<controls:CodeViewer> | ||
<Grid> | ||
<Grid.RowDefinitions> | ||
<RowDefinition Height="Auto" /> | ||
<RowDefinition Height="Auto" /> | ||
</Grid.RowDefinitions> | ||
<ToggleButton | ||
x:Name="MyBadgeToggleButton" | ||
Margin="10" | ||
HorizontalAlignment="Center" | ||
Content="显示Badge" /> | ||
<StackPanel | ||
Grid.Row="1" | ||
HorizontalAlignment="Center" | ||
Orientation="Horizontal"> | ||
<Button | ||
wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" | ||
wd:Badge.Text="new" | ||
Content="Default" | ||
Style="{DynamicResource WD.PrimaryButton}" /> | ||
<Button | ||
Margin="40,0" | ||
wd:Badge.FontSize="12" | ||
wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" | ||
wd:Badge.Text="3" | ||
Content="Success" | ||
Style="{DynamicResource WD.SuccessDefaultButton}" /> | ||
<Button | ||
wd:Badge.FontSize="12" | ||
wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" | ||
wd:Badge.Text="10+" | ||
Content="Warning" | ||
Style="{DynamicResource WD.WarningDefaultButton}" /> | ||
<Button | ||
Margin="40,0" | ||
wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" | ||
wd:Badge.Text="NEW" | ||
Content="Danger" | ||
Style="{DynamicResource WD.DangerDefaultButton}" /> | ||
<Rectangle | ||
Width="100" | ||
Height="100" | ||
wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" | ||
Fill="Aqua" /> | ||
</StackPanel> | ||
</Grid> | ||
<controls:CodeViewer.SourceCodes> | ||
<controls:SourceCodeModel CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/BadgeExample.xaml" CodeType="Xaml" /> | ||
<controls:SourceCodeModel CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/BadgeExample.xaml.cs" CodeType="CSharp" /> | ||
</controls:CodeViewer.SourceCodes> | ||
</controls:CodeViewer> | ||
</UserControl> |
15 changes: 15 additions & 0 deletions
15
src/WPFDevelopers.Samples.Shared/ExampleViews/BadgeExample.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System.Windows.Controls; | ||
|
||
namespace WPFDevelopers.Samples.ExampleViews | ||
{ | ||
/// <summary> | ||
/// BarrageExample.xaml 的交互逻辑 | ||
/// </summary> | ||
public partial class BadgeExample : UserControl | ||
{ | ||
public BadgeExample() | ||
{ | ||
InitializeComponent(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
using System; | ||
using System.Windows; | ||
using System.Windows.Documents; | ||
using System.Windows.Media; | ||
|
||
namespace WPFDevelopers.Controls | ||
{ | ||
public class Badge : Adorner | ||
{ | ||
public static readonly DependencyProperty TextProperty = | ||
DependencyProperty.Register("Text", typeof(string), typeof(Badge), new PropertyMetadata(string.Empty)); | ||
|
||
public static readonly DependencyProperty FontSizeProperty = | ||
DependencyProperty.Register("FontSize", typeof(double), typeof(Badge), new PropertyMetadata(10.0d)); | ||
|
||
|
||
public static readonly DependencyProperty IsShowProperty = | ||
DependencyProperty.RegisterAttached("IsShow", typeof(bool), typeof(Badge), | ||
new PropertyMetadata(false, OnIsBadgeChanged)); | ||
|
||
private readonly double _size; | ||
|
||
private readonly string _text; | ||
|
||
public Badge(UIElement adornedElement, string text = null, double size = 0) | ||
: base(adornedElement) | ||
{ | ||
_text = text; | ||
_size = size; | ||
ToolTip = text; | ||
} | ||
|
||
public string Text | ||
{ | ||
get => (string) GetValue(TextProperty); | ||
set => SetValue(TextProperty, value); | ||
} | ||
|
||
public double FontSize | ||
{ | ||
get => (double) GetValue(FontSizeProperty); | ||
set => SetValue(FontSizeProperty, value); | ||
} | ||
|
||
public static string GetText(UIElement element) | ||
{ | ||
if (element == null) throw new ArgumentNullException("Text"); | ||
|
||
return (string) element.GetValue(TextProperty); | ||
} | ||
|
||
public static void SetText(UIElement element, string Text) | ||
{ | ||
if (element == null) throw new ArgumentNullException("Text"); | ||
|
||
element.SetValue(TextProperty, Text); | ||
} | ||
|
||
public static double GetFontSize(UIElement element) | ||
{ | ||
if (element == null) throw new ArgumentNullException("FontSize"); | ||
|
||
return (double) element.GetValue(FontSizeProperty); | ||
} | ||
|
||
public static void SetFontSize(UIElement element, string Text) | ||
{ | ||
if (element == null) throw new ArgumentNullException("FontSize"); | ||
|
||
element.SetValue(FontSizeProperty, Text); | ||
} | ||
|
||
private static void OnIsBadgeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
if (e.NewValue is bool isBadge && d is FrameworkElement parent) | ||
{ | ||
if (isBadge) | ||
{ | ||
parent.IsVisibleChanged += Parent_IsVisibleChanged; | ||
if (!parent.IsLoaded) | ||
parent.Loaded += Parent_Loaded; | ||
else | ||
CreateBadge(parent); | ||
} | ||
else | ||
{ | ||
parent.Loaded -= Parent_Loaded; | ||
parent.IsVisibleChanged -= Parent_IsVisibleChanged; | ||
CreateBadge(parent, true); | ||
} | ||
} | ||
} | ||
private static void Parent_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) | ||
{ | ||
|
||
if (e.NewValue is bool isVisible && sender is FrameworkElement parent) | ||
{ | ||
var isShow = GetIsShow(parent); | ||
if (isVisible && isShow) | ||
CreateBadge(parent); | ||
} | ||
} | ||
private static void Parent_Loaded(object sender, RoutedEventArgs e) | ||
{ | ||
if (sender is UIElement element) | ||
CreateBadge(element); | ||
} | ||
|
||
private static void CreateBadge(UIElement uIElement, bool isRemove = false) | ||
{ | ||
var layer = AdornerLayer.GetAdornerLayer(uIElement); | ||
if (layer == null) return; | ||
if (isRemove && uIElement != null) | ||
{ | ||
var adorners = layer.GetAdorners(uIElement); | ||
if (adorners != null) | ||
foreach (var item in adorners) | ||
if (item is Badge container) | ||
layer.Remove(container); | ||
return; | ||
} | ||
|
||
var value = GetText(uIElement); | ||
var size = GetFontSize(uIElement); | ||
var badgeAdorner = new Badge(uIElement, value, size); | ||
layer.Add(badgeAdorner); | ||
} | ||
|
||
public static bool GetIsShow(DependencyObject obj) | ||
{ | ||
return (bool) obj.GetValue(IsShowProperty); | ||
} | ||
|
||
public static void SetIsShow(DependencyObject obj, bool value) | ||
{ | ||
obj.SetValue(IsShowProperty, value); | ||
} | ||
|
||
protected override void OnRender(DrawingContext drawingContext) | ||
{ | ||
var adornedElement = AdornedElement as FrameworkElement; | ||
var margin = adornedElement.Margin; | ||
var desiredWidth = adornedElement.DesiredSize.Width - margin.Left - margin.Right; | ||
var brush = new SolidColorBrush((Color) Application.Current.TryFindResource("WD.DangerColor")); | ||
brush.Freeze(); | ||
var radius = 5.0; | ||
var center = new Point(desiredWidth, 0); | ||
FormattedText formattedText = null; | ||
if (!string.IsNullOrEmpty(_text)) | ||
formattedText = DrawingContextHelper.GetFormattedText( | ||
_text, | ||
Brushes.White, | ||
FlowDirection.LeftToRight, | ||
_size); | ||
var pen = new Pen(Brushes.White, .3); | ||
pen.Freeze(); | ||
drawingContext.PushTransform(new MatrixTransform(Matrix.Identity)); | ||
if (formattedText != null) | ||
{ | ||
var height = formattedText.Height; | ||
var width = formattedText.Width > 20 ? 20 : formattedText.Width; | ||
var isSingle = false; | ||
if (_text.Length == 1) | ||
{ | ||
var max = formattedText.Width > formattedText.Height ? formattedText.Width : formattedText.Height; | ||
height = max; | ||
width = max; | ||
isSingle = true; | ||
} | ||
|
||
var startPoint = new Point(0, 0); | ||
var endPoint = new Point(0, 0); | ||
if (!isSingle) | ||
{ | ||
startPoint = new Point(center.X - width / 1.4, center.Y - height / 1.8); | ||
endPoint = new Point(center.X + width / 1.4 + 6, center.Y + height / 1.8); | ||
} | ||
else | ||
{ | ||
startPoint = new Point(center.X - width / 2, center.Y - height / 2); | ||
endPoint = new Point(center.X + width / 2, center.Y + height / 2); | ||
} | ||
|
||
var rect = new Rect(startPoint, endPoint); | ||
drawingContext.DrawRoundedRectangle(brush, pen, rect, 8, 8); | ||
formattedText.MaxTextWidth = width + 10; | ||
var centerRect = new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); | ||
var textPosition = new Point(centerRect.X - formattedText.Width / 2, | ||
centerRect.Y - formattedText.Height / 2); | ||
drawingContext.DrawText(formattedText, textPosition); | ||
} | ||
else | ||
{ | ||
drawingContext.DrawEllipse(brush, pen, center, radius, radius); | ||
} | ||
|
||
drawingContext.Pop(); | ||
RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified); | ||
} | ||
} | ||
} |