feat: Add Rate styles and demos.
This commit is contained in:
1 parent
4d5f453895
commit
db0ced2f00
8 files changed
+685
-1
No files matched your search
@@ -52,7 +52,8 @@
|
||||
[ "WaterfallPanel", "WaterfallPanelDemo", "Brush.Panel", "", "Layout" ],
|
||||
[ "HoneycombPanel", "HoneycombPanelDemo", "Brush.PolygonHexagon", "", "Layout" ],
|
||||
[ "UniformSpacingPanel", "UniformSpacingPanelDemo", "Brush.IncreaseHorizontalSpacing", "", "Layout" ],
|
||||
[ "ProgressBar", "ProgressBarDemo", "Brush.ProgressBar", "", "Feedback" ]
|
||||
[ "ProgressBar", "ProgressBarDemo", "Brush.ProgressBar", "", "Feedback" ],
|
||||
[ "Rate", "RateDemo", "Brush.Favorite", "", "Feedback" ]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,35 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
x:Class="HandyControlDemo.UserControl.RateDemo"
|
||||
Background="{DynamicResource RegionBrush}">
|
||||
<TransitioningContentControl>
|
||||
<StackPanel Margin="32"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="190">
|
||||
<hc:Rate Value="2" />
|
||||
<hc:Rate Value="5"
|
||||
Count="6"
|
||||
Margin="0,16,0,0"
|
||||
Foreground="{DynamicResource SuccessBrush}" />
|
||||
<hc:Rate DefaultValue="3"
|
||||
IsReadOnly="True"
|
||||
AllowHalf="True"
|
||||
Margin="0,16,0,0"
|
||||
Foreground="{DynamicResource WarningBrush}" />
|
||||
<hc:Rate DefaultValue="1"
|
||||
AllowClear="False"
|
||||
AllowHalf="True"
|
||||
Margin="0,16,0,0"
|
||||
Foreground="{DynamicResource DangerBrush}"
|
||||
Icon="{StaticResource LoveGeometry}" />
|
||||
<hc:Rate Value="4.5"
|
||||
AllowHalf="True"
|
||||
ShowText="True"
|
||||
Margin="0,16,0,0"
|
||||
Foreground="{DynamicResource DangerBrush}"
|
||||
Icon="{StaticResource LoveGeometry}" />
|
||||
</StackPanel>
|
||||
</TransitioningContentControl>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace HandyControlDemo.UserControl;
|
||||
|
||||
public partial class RateDemo : Avalonia.Controls.UserControl
|
||||
{
|
||||
public RateDemo()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using HandyControl.Data;
|
||||
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
public class Rate : ItemsControl
|
||||
{
|
||||
public static readonly StyledProperty<bool> AllowHalfProperty =
|
||||
AvaloniaProperty.Register<Rate, bool>(nameof(AllowHalf), inherits: true);
|
||||
|
||||
public static readonly StyledProperty<bool> AllowClearProperty =
|
||||
AvaloniaProperty.Register<Rate, bool>(nameof(AllowClear), true, inherits: true);
|
||||
|
||||
public static readonly StyledProperty<Geometry?> IconProperty =
|
||||
AvaloniaProperty.Register<Rate, Geometry?>(nameof(Icon), inherits: true);
|
||||
|
||||
public static readonly StyledProperty<int> CountProperty =
|
||||
AvaloniaProperty.Register<Rate, int>(nameof(Count), 5);
|
||||
|
||||
public static readonly StyledProperty<double> DefaultValueProperty =
|
||||
AvaloniaProperty.Register<Rate, double>(nameof(DefaultValue));
|
||||
|
||||
public static readonly StyledProperty<double> ValueProperty =
|
||||
AvaloniaProperty.Register<Rate, double>(nameof(Value));
|
||||
|
||||
public static readonly StyledProperty<string?> TextProperty =
|
||||
AvaloniaProperty.Register<Rate, string?>(nameof(Text));
|
||||
|
||||
public static readonly StyledProperty<bool> ShowTextProperty =
|
||||
AvaloniaProperty.Register<Rate, bool>(nameof(ShowText));
|
||||
|
||||
public static readonly StyledProperty<bool> IsReadOnlyProperty =
|
||||
AvaloniaProperty.Register<Rate, bool>(nameof(IsReadOnly));
|
||||
|
||||
public static readonly StyledProperty<double> ItemWidthProperty =
|
||||
AvaloniaProperty.Register<Rate, double>(nameof(ItemWidth), 20);
|
||||
|
||||
public static readonly StyledProperty<double> ItemHeightProperty =
|
||||
AvaloniaProperty.Register<Rate, double>(nameof(ItemHeight), 20);
|
||||
|
||||
public static readonly StyledProperty<Thickness> ItemMarginProperty =
|
||||
AvaloniaProperty.Register<Rate, Thickness>(nameof(ItemMargin));
|
||||
|
||||
public static readonly RoutedEvent<FunctionEventArgs<double>> ValueChangedEvent =
|
||||
RoutedEvent.Register<Rate, FunctionEventArgs<double>>(nameof(ValueChanged), RoutingStrategies.Bubble);
|
||||
|
||||
private readonly List<RateItem> _rateItems = [];
|
||||
private bool _isLoaded;
|
||||
private bool _isUpdatingItems;
|
||||
|
||||
static Rate()
|
||||
{
|
||||
FocusableProperty.OverrideDefaultValue<Rate>(false);
|
||||
CountProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.RebuildItems());
|
||||
AllowHalfProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
AllowClearProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
IconProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
IsReadOnlyProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
BackgroundProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
ItemWidthProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
ItemHeightProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
ItemMarginProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
ForegroundProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.UpdateItemProperties());
|
||||
DefaultValueProperty.Changed.AddClassHandler<Rate>((rate, _) => rate.ApplyDefaultValue());
|
||||
ValueProperty.Changed.AddClassHandler<Rate>((rate, e) => rate.OnValueChanged(e));
|
||||
}
|
||||
|
||||
public event EventHandler<FunctionEventArgs<double>> ValueChanged
|
||||
{
|
||||
add => AddHandler(ValueChangedEvent, value);
|
||||
remove => RemoveHandler(ValueChangedEvent, value);
|
||||
}
|
||||
|
||||
public bool AllowHalf
|
||||
{
|
||||
get => GetValue(AllowHalfProperty);
|
||||
set => SetValue(AllowHalfProperty, value);
|
||||
}
|
||||
|
||||
public bool AllowClear
|
||||
{
|
||||
get => GetValue(AllowClearProperty);
|
||||
set => SetValue(AllowClearProperty, value);
|
||||
}
|
||||
|
||||
public Geometry? Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get => GetValue(CountProperty);
|
||||
set => SetValue(CountProperty, value);
|
||||
}
|
||||
|
||||
public double DefaultValue
|
||||
{
|
||||
get => GetValue(DefaultValueProperty);
|
||||
set => SetValue(DefaultValueProperty, value);
|
||||
}
|
||||
|
||||
public double Value
|
||||
{
|
||||
get => GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
}
|
||||
|
||||
public string? Text
|
||||
{
|
||||
get => GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public bool ShowText
|
||||
{
|
||||
get => GetValue(ShowTextProperty);
|
||||
set => SetValue(ShowTextProperty, value);
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get => GetValue(IsReadOnlyProperty);
|
||||
set => SetValue(IsReadOnlyProperty, value);
|
||||
}
|
||||
|
||||
public double ItemWidth
|
||||
{
|
||||
get => GetValue(ItemWidthProperty);
|
||||
set => SetValue(ItemWidthProperty, value);
|
||||
}
|
||||
|
||||
public double ItemHeight
|
||||
{
|
||||
get => GetValue(ItemHeightProperty);
|
||||
set => SetValue(ItemHeightProperty, value);
|
||||
}
|
||||
|
||||
public Thickness ItemMargin
|
||||
{
|
||||
get => GetValue(ItemMarginProperty);
|
||||
set => SetValue(ItemMarginProperty, value);
|
||||
}
|
||||
|
||||
protected override void OnLoaded(RoutedEventArgs e)
|
||||
{
|
||||
base.OnLoaded(e);
|
||||
|
||||
RebuildItems();
|
||||
_isLoaded = true;
|
||||
ApplyDefaultValue();
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
protected override void OnPointerExited(PointerEventArgs e)
|
||||
{
|
||||
base.OnPointerExited(e);
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
public void Reset() => Value = DefaultValue;
|
||||
|
||||
private void OnValueChanged(AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
var value = CoerceValue(e.GetNewValue<double>());
|
||||
if (!value.Equals(Value))
|
||||
{
|
||||
SetCurrentValue(ValueProperty, value);
|
||||
return;
|
||||
}
|
||||
|
||||
SetCurrentValue(TextProperty, value.ToString("0.0", CultureInfo.CurrentCulture));
|
||||
RaiseEvent(new FunctionEventArgs<double>(ValueChangedEvent, this) { Info = value });
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
private double CoerceValue(double value)
|
||||
{
|
||||
if (double.IsNaN(value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var max = Math.Max(0, Count);
|
||||
return Math.Clamp(value, 0, max);
|
||||
}
|
||||
|
||||
private void ApplyDefaultValue()
|
||||
{
|
||||
if (!_isLoaded || Value > 0 || DefaultValue <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
private void RebuildItems()
|
||||
{
|
||||
foreach (var item in _rateItems)
|
||||
{
|
||||
item.SelectedChanged -= RateItemSelectedChanged;
|
||||
item.ValueChanged -= RateItemValueChanged;
|
||||
}
|
||||
|
||||
_rateItems.Clear();
|
||||
Items.Clear();
|
||||
|
||||
for (var i = 1; i <= Count; i++)
|
||||
{
|
||||
var item = new RateItem { Index = i };
|
||||
item.SelectedChanged += RateItemSelectedChanged;
|
||||
item.ValueChanged += RateItemValueChanged;
|
||||
_rateItems.Add(item);
|
||||
Items.Add(item);
|
||||
}
|
||||
|
||||
UpdateItemProperties();
|
||||
UpdateItems();
|
||||
}
|
||||
|
||||
private void UpdateItemProperties()
|
||||
{
|
||||
foreach (var item in _rateItems)
|
||||
{
|
||||
item.Width = ItemWidth;
|
||||
item.Height = ItemHeight;
|
||||
item.Margin = ItemMargin;
|
||||
item.AllowHalf = AllowHalf;
|
||||
item.AllowClear = AllowClear;
|
||||
item.Icon = Icon;
|
||||
item.IsReadOnly = IsReadOnly;
|
||||
item.Background = Background;
|
||||
item.Foreground = Foreground;
|
||||
}
|
||||
}
|
||||
|
||||
private void RateItemValueChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (_isUpdatingItems)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Value = _rateItems.Where(item => item.IsSelected).Sum(item => item.IsHalf ? 0.5 : 1);
|
||||
}
|
||||
|
||||
private void RateItemSelectedChanged(object? sender, EventArgs e)
|
||||
{
|
||||
if (sender is not RateItem rateItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var index = rateItem.Index;
|
||||
_isUpdatingItems = true;
|
||||
|
||||
for (var i = 0; i < index - 1 && i < _rateItems.Count; i++)
|
||||
{
|
||||
_rateItems[i].IsSelected = true;
|
||||
_rateItems[i].IsHalf = false;
|
||||
}
|
||||
|
||||
for (var i = index; i < _rateItems.Count; i++)
|
||||
{
|
||||
_rateItems[i].IsSelected = false;
|
||||
_rateItems[i].IsHalf = false;
|
||||
}
|
||||
|
||||
_isUpdatingItems = false;
|
||||
}
|
||||
|
||||
private void UpdateItems()
|
||||
{
|
||||
if (!_isLoaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isUpdatingItems = true;
|
||||
var value = CoerceValue(Value);
|
||||
var wholeCount = (int)value;
|
||||
|
||||
for (var i = 0; i < wholeCount && i < _rateItems.Count; i++)
|
||||
{
|
||||
_rateItems[i].IsSelected = true;
|
||||
_rateItems[i].IsHalf = false;
|
||||
}
|
||||
|
||||
if (value > wholeCount && wholeCount < _rateItems.Count)
|
||||
{
|
||||
_rateItems[wholeCount].IsSelected = true;
|
||||
_rateItems[wholeCount].IsHalf = true;
|
||||
wholeCount++;
|
||||
}
|
||||
|
||||
for (var i = wholeCount; i < _rateItems.Count; i++)
|
||||
{
|
||||
_rateItems[i].IsSelected = false;
|
||||
_rateItems[i].IsHalf = false;
|
||||
}
|
||||
|
||||
_isUpdatingItems = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
[TemplatePart(ElementIcon, typeof(Control))]
|
||||
public class RateItem : TemplatedControl
|
||||
{
|
||||
private const string ElementIcon = "PART_Icon";
|
||||
|
||||
public static readonly StyledProperty<bool> AllowClearProperty =
|
||||
AvaloniaProperty.Register<RateItem, bool>(nameof(AllowClear), true);
|
||||
|
||||
public static readonly StyledProperty<bool> AllowHalfProperty =
|
||||
AvaloniaProperty.Register<RateItem, bool>(nameof(AllowHalf));
|
||||
|
||||
public static readonly StyledProperty<Geometry?> IconProperty =
|
||||
AvaloniaProperty.Register<RateItem, Geometry?>(nameof(Icon));
|
||||
|
||||
public static readonly StyledProperty<bool> IsReadOnlyProperty =
|
||||
AvaloniaProperty.Register<RateItem, bool>(nameof(IsReadOnly));
|
||||
|
||||
internal static readonly StyledProperty<bool> IsSelectedProperty =
|
||||
AvaloniaProperty.Register<RateItem, bool>(nameof(IsSelected));
|
||||
|
||||
private Control? _icon;
|
||||
private bool _isHalf;
|
||||
private bool _isPointerPressed;
|
||||
private bool _isSentValue;
|
||||
|
||||
public event EventHandler? SelectedChanged;
|
||||
|
||||
public event EventHandler? ValueChanged;
|
||||
|
||||
static RateItem()
|
||||
{
|
||||
FocusableProperty.OverrideDefaultValue<RateItem>(false);
|
||||
IsSelectedProperty.Changed.AddClassHandler<RateItem>((item, _) => item.UpdateIcon());
|
||||
}
|
||||
|
||||
public bool AllowClear
|
||||
{
|
||||
get => GetValue(AllowClearProperty);
|
||||
set => SetValue(AllowClearProperty, value);
|
||||
}
|
||||
|
||||
public bool AllowHalf
|
||||
{
|
||||
get => GetValue(AllowHalfProperty);
|
||||
set => SetValue(AllowHalfProperty, value);
|
||||
}
|
||||
|
||||
public Geometry? Icon
|
||||
{
|
||||
get => GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get => GetValue(IsReadOnlyProperty);
|
||||
set => SetValue(IsReadOnlyProperty, value);
|
||||
}
|
||||
|
||||
internal bool IsSelected
|
||||
{
|
||||
get => GetValue(IsSelectedProperty);
|
||||
set => SetValue(IsSelectedProperty, value);
|
||||
}
|
||||
|
||||
internal bool IsHalf
|
||||
{
|
||||
get => _isHalf;
|
||||
set
|
||||
{
|
||||
if (_isHalf == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isHalf = value;
|
||||
UpdateIcon();
|
||||
}
|
||||
}
|
||||
|
||||
internal int Index { get; set; }
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
|
||||
_icon = e.NameScope.Find<Control>(ElementIcon);
|
||||
UpdateIcon();
|
||||
}
|
||||
|
||||
protected override void OnPointerEntered(PointerEventArgs e)
|
||||
{
|
||||
base.OnPointerEntered(e);
|
||||
if (IsReadOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isSentValue = false;
|
||||
IsSelected = true;
|
||||
SelectedChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected override void OnPointerMoved(PointerEventArgs e)
|
||||
{
|
||||
base.OnPointerMoved(e);
|
||||
if (IsReadOnly || !AllowHalf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var point = e.GetPosition(this);
|
||||
IsHalf = point.X < Bounds.Width / 2;
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
{
|
||||
base.OnPointerPressed(e);
|
||||
if (IsReadOnly || !e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isPointerPressed = true;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
||||
{
|
||||
base.OnPointerReleased(e);
|
||||
if (IsReadOnly || !_isPointerPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Index == 1 && AllowClear)
|
||||
{
|
||||
if (IsSelected)
|
||||
{
|
||||
if (!_isSentValue)
|
||||
{
|
||||
ValueChanged?.Invoke(this, EventArgs.Empty);
|
||||
_isPointerPressed = false;
|
||||
_isSentValue = true;
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_isSentValue = false;
|
||||
IsSelected = false;
|
||||
IsHalf = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsSelected = true;
|
||||
if (AllowHalf)
|
||||
{
|
||||
var point = e.GetPosition(this);
|
||||
IsHalf = point.X < Bounds.Width / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ValueChanged?.Invoke(this, EventArgs.Empty);
|
||||
_isPointerPressed = false;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnPointerExited(PointerEventArgs e)
|
||||
{
|
||||
base.OnPointerExited(e);
|
||||
if (IsReadOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isPointerPressed = false;
|
||||
}
|
||||
|
||||
private void UpdateIcon()
|
||||
{
|
||||
if (_icon == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_icon.IsVisible = IsSelected;
|
||||
var width = double.IsNaN(Width) ? Bounds.Width : Width;
|
||||
_icon.Width = IsHalf ? width / 2 : double.NaN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace HandyControl.Data;
|
||||
|
||||
public class FunctionEventArgs<T> : RoutedEventArgs
|
||||
{
|
||||
public FunctionEventArgs(T info)
|
||||
{
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public FunctionEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source)
|
||||
{
|
||||
}
|
||||
|
||||
public T Info { get; set; } = default!;
|
||||
}
|
||||
@@ -48,6 +48,7 @@
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/TreeView.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Label.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Slider.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Rate.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Expander.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ProgressBar.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Calendar.axaml" />
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:ClassModifier="internal"
|
||||
xmlns:hc="clr-namespace:HandyControl.Controls">
|
||||
|
||||
<ControlTheme x:Key="RateItemBaseStyle"
|
||||
TargetType="hc:RateItem">
|
||||
<Setter Property="Focusable"
|
||||
Value="False" />
|
||||
<Setter Property="ClipToBounds"
|
||||
Value="False" />
|
||||
<Setter Property="RenderTransformOrigin"
|
||||
Value="50%,50%" />
|
||||
<Setter Property="RenderTransform">
|
||||
<ScaleTransform ScaleX="1"
|
||||
ScaleY="1" />
|
||||
</Setter>
|
||||
<Setter Property="Transitions">
|
||||
<Transitions>
|
||||
<TransformOperationsTransition Property="RenderTransform"
|
||||
Duration="0:0:0.12" />
|
||||
</Transitions>
|
||||
</Setter>
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Panel Background="Transparent">
|
||||
<Path Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}"
|
||||
Data="{TemplateBinding Icon}"
|
||||
Fill="{TemplateBinding Background}"
|
||||
Stretch="Uniform" />
|
||||
<Border x:Name="PART_Icon"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
ClipToBounds="True"
|
||||
IsVisible="False">
|
||||
<Path Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Data="{TemplateBinding Icon}"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Stretch="Uniform" />
|
||||
</Border>
|
||||
</Panel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Style Selector="^:pointerover">
|
||||
<Setter Property="RenderTransform">
|
||||
<ScaleTransform ScaleX="1.1"
|
||||
ScaleY="1.1" />
|
||||
</Setter>
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
|
||||
<ControlTheme x:Key="RateBaseStyle"
|
||||
TargetType="hc:Rate">
|
||||
<Setter Property="Focusable"
|
||||
Value="False" />
|
||||
<Setter Property="ItemWidth"
|
||||
Value="20" />
|
||||
<Setter Property="ItemHeight"
|
||||
Value="20" />
|
||||
<Setter Property="ItemMargin"
|
||||
Value="5,0" />
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Left" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Top" />
|
||||
<Setter Property="Icon"
|
||||
Value="{StaticResource StarGeometry}" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource PrimaryBrush}" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource SecondaryRegionBrush}" />
|
||||
<Setter Property="ItemContainerTheme"
|
||||
Value="{StaticResource RateItemBaseStyle}" />
|
||||
<Setter Property="ClipToBounds"
|
||||
Value="False" />
|
||||
<Setter Property="ItemsPanel">
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Margin="-5,0" />
|
||||
</ItemsPanelTemplate>
|
||||
</Setter>
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<StackPanel Background="Transparent"
|
||||
Orientation="Horizontal">
|
||||
<ItemsPresenter ItemsPanel="{TemplateBinding ItemsPanel}" />
|
||||
<TextBlock Text="{TemplateBinding Text}"
|
||||
Margin="10,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
IsVisible="{TemplateBinding ShowText}" />
|
||||
</StackPanel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
</ControlTheme>
|
||||
|
||||
<ControlTheme x:Key="{x:Type hc:Rate}"
|
||||
BasedOn="{StaticResource RateBaseStyle}"
|
||||
TargetType="hc:Rate" />
|
||||
</ResourceDictionary>
|
||||
Reference in new issue
Block a user