committed by
GitHub
38 changed files with 1306 additions and 585 deletions
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Styling |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The `^` nesting style selector.
|
||||
|
/// </summary>
|
||||
|
internal class NestingSelector : Selector |
||||
|
{ |
||||
|
public override bool InTemplate => false; |
||||
|
public override bool IsCombinator => false; |
||||
|
public override Type? TargetType => null; |
||||
|
|
||||
|
public override string ToString() => "^"; |
||||
|
|
||||
|
protected override SelectorMatch Evaluate(IStyleable control, IStyle? parent, bool subscribe) |
||||
|
{ |
||||
|
if (parent is Style s && s.Selector is Selector selector) |
||||
|
{ |
||||
|
return selector.Match(control, (parent as Style)?.Parent, subscribe); |
||||
|
} |
||||
|
|
||||
|
throw new InvalidOperationException( |
||||
|
"Nesting selector was specified but cannot determine parent selector."); |
||||
|
} |
||||
|
|
||||
|
protected override Selector? MovePrevious() => null; |
||||
|
internal override bool HasValidNestingSelector() => true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Avalonia.Styling |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Simple cache for improving performance of applying styles.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Maps <see cref="IStyleable.StyleKey"/> to a list of styles that are known be be possible
|
||||
|
/// matches.
|
||||
|
/// </remarks>
|
||||
|
internal class StyleCache : Dictionary<Type, List<IStyle>?> |
||||
|
{ |
||||
|
public SelectorMatchResult TryAttach(IList<IStyle> styles, IStyleable target, IStyleHost? host) |
||||
|
{ |
||||
|
if (TryGetValue(target.StyleKey, out var cached)) |
||||
|
{ |
||||
|
if (cached is object) |
||||
|
{ |
||||
|
var result = SelectorMatchResult.NeverThisType; |
||||
|
|
||||
|
foreach (var style in cached) |
||||
|
{ |
||||
|
var childResult = style.TryAttach(target, host); |
||||
|
if (childResult > result) |
||||
|
result = childResult; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return SelectorMatchResult.NeverThisType; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
List<IStyle>? matches = null; |
||||
|
|
||||
|
foreach (var child in styles) |
||||
|
{ |
||||
|
if (child.TryAttach(target, host) != SelectorMatchResult.NeverThisType) |
||||
|
{ |
||||
|
matches ??= new List<IStyle>(); |
||||
|
matches.Add(child); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Add(target.StyleKey, matches); |
||||
|
|
||||
|
return matches is null ? |
||||
|
SelectorMatchResult.NeverThisType : |
||||
|
SelectorMatchResult.AlwaysThisType; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using System.Collections.ObjectModel; |
||||
|
using Avalonia.Controls; |
||||
|
|
||||
|
namespace Avalonia.Styling |
||||
|
{ |
||||
|
internal class StyleChildren : Collection<IStyle> |
||||
|
{ |
||||
|
private readonly Style _owner; |
||||
|
|
||||
|
public StyleChildren(Style owner) => _owner = owner; |
||||
|
|
||||
|
protected override void InsertItem(int index, IStyle item) |
||||
|
{ |
||||
|
(item as Style)?.SetParent(_owner); |
||||
|
base.InsertItem(index, item); |
||||
|
} |
||||
|
|
||||
|
protected override void RemoveItem(int index) |
||||
|
{ |
||||
|
var item = Items[index]; |
||||
|
(item as Style)?.SetParent(null); |
||||
|
if (_owner.Owner is IResourceHost host) |
||||
|
(item as IResourceProvider)?.RemoveOwner(host); |
||||
|
base.RemoveItem(index); |
||||
|
} |
||||
|
|
||||
|
protected override void SetItem(int index, IStyle item) |
||||
|
{ |
||||
|
(item as Style)?.SetParent(_owner); |
||||
|
base.SetItem(index, item); |
||||
|
if (_owner.Owner is IResourceHost host) |
||||
|
(item as IResourceProvider)?.AddOwner(host); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,294 +1,321 @@ |
|||||
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
<Style xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
Selector="CheckBox"> |
||||
<Design.PreviewWith> |
<Design.PreviewWith> |
||||
<Border Padding="20"> |
<Border Padding="20"> |
||||
<CheckBox IsThreeState="True" IsChecked="True" Content="Content" Foreground="Gold" /> |
<CheckBox IsThreeState="True" IsChecked="True" Content="Content" Foreground="Gold" /> |
||||
</Border> |
</Border> |
||||
</Design.PreviewWith> |
</Design.PreviewWith> |
||||
<Style Selector="CheckBox"> |
|
||||
<Setter Property="Padding" Value="8,0,0,0" /> |
<Setter Property="Padding" Value="8,0,0,0" /> |
||||
<Setter Property="HorizontalAlignment" Value="Left" /> |
<Setter Property="HorizontalAlignment" Value="Left" /> |
||||
<Setter Property="VerticalAlignment" Value="Center" /> |
<Setter Property="VerticalAlignment" Value="Center" /> |
||||
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
||||
<Setter Property="VerticalContentAlignment" Value="Center" /> |
<Setter Property="VerticalContentAlignment" Value="Center" /> |
||||
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> |
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" /> |
||||
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" /> |
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" /> |
||||
<Setter Property="MinHeight" Value="32" /> |
<Setter Property="MinHeight" Value="32" /> |
||||
<!--<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" /> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUnchecked}" /> |
||||
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />--> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUnchecked}" /> |
||||
<Setter Property="Template"> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUnchecked}" /> |
||||
<ControlTemplate> |
<Setter Property="Template"> |
||||
<Grid x:Name="RootGrid" ColumnDefinitions="20,*"> |
<ControlTemplate> |
||||
<Border x:Name="PART_Border" |
<Grid x:Name="RootGrid" ColumnDefinitions="20,*"> |
||||
Grid.ColumnSpan="2" |
<Border x:Name="PART_Border" |
||||
Background="{TemplateBinding Background}" |
Grid.ColumnSpan="2" |
||||
BorderBrush="{TemplateBinding BorderBrush}" |
Background="{TemplateBinding Background}" |
||||
BorderThickness="{TemplateBinding BorderThickness}" |
BorderBrush="{TemplateBinding BorderBrush}" |
||||
CornerRadius="{TemplateBinding CornerRadius}" /> |
BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
CornerRadius="{TemplateBinding CornerRadius}" /> |
||||
<Grid VerticalAlignment="Top" Height="32"> |
|
||||
<Border x:Name="NormalRectangle" |
<Grid VerticalAlignment="Top" Height="32"> |
||||
BorderThickness="{DynamicResource CheckBoxBorderThemeThickness}" |
<Border x:Name="NormalRectangle" |
||||
CornerRadius="{TemplateBinding CornerRadius}" |
BorderThickness="{DynamicResource CheckBoxBorderThemeThickness}" |
||||
UseLayoutRounding="False" |
CornerRadius="{TemplateBinding CornerRadius}" |
||||
Height="20" |
UseLayoutRounding="False" |
||||
Width="20" /> |
Height="20" |
||||
|
Width="20" /> |
||||
<Viewbox UseLayoutRounding="False"> |
|
||||
<Panel> |
<Viewbox UseLayoutRounding="False"> |
||||
<Panel Height="16" Width="16" /> |
<Panel> |
||||
<Path x:Name="CheckGlyph" Stretch="Uniform" VerticalAlignment="Center" /> |
<Panel Height="16" Width="16" /> |
||||
</Panel> |
<Path x:Name="CheckGlyph" Stretch="Uniform" VerticalAlignment="Center" /> |
||||
</Viewbox> |
</Panel> |
||||
</Grid> |
</Viewbox> |
||||
<ContentPresenter x:Name="ContentPresenter" |
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}" |
|
||||
Content="{TemplateBinding Content}" |
|
||||
Margin="{TemplateBinding Padding}" |
|
||||
RecognizesAccessKey="True" |
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
|
||||
Grid.Column="1" /> |
|
||||
<!-- TODO: TextWrapping="Wrap" on contentpresenter --> |
|
||||
</Grid> |
</Grid> |
||||
</ControlTemplate> |
<ContentPresenter x:Name="ContentPresenter" |
||||
</Setter> |
ContentTemplate="{TemplateBinding ContentTemplate}" |
||||
</Style> |
Content="{TemplateBinding Content}" |
||||
|
Margin="{TemplateBinding Padding}" |
||||
<!-- Unchecked Normal State --> |
RecognizesAccessKey="True" |
||||
<Style Selector="CheckBox"> |
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUnchecked}" /> |
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
||||
</Style> |
Grid.Column="1" /> |
||||
|
<!-- TODO: TextWrapping="Wrap" on contentpresenter --> |
||||
<Style Selector="CheckBox"> |
</Grid> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUnchecked}" /> |
</ControlTemplate> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUnchecked}" /> |
</Setter> |
||||
</Style> |
|
||||
|
<Style.Children> |
||||
<Style Selector="CheckBox /template/ Border#NormalRectangle"> |
<!-- Unchecked Normal State --> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUnchecked}" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUnchecked}" /> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUnchecked}" /> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUnchecked}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox /template/ Path#CheckGlyph"> |
|
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUnchecked}" /> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
<Setter Property="Opacity" Value="0" /> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUnchecked}" /> |
||||
</Style> |
<Setter Property="Opacity" Value="0" /> |
||||
|
</Style> |
||||
<!-- Unchecked PointerOver State --> |
|
||||
<Style Selector="CheckBox:pointerover /template/ ContentPresenter#ContentPresenter"> |
<!-- Unchecked PointerOver State --> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUncheckedPointerOver}" /> |
<Style Selector="^:pointerover"> |
||||
</Style> |
<Style.Children> |
||||
|
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
<Style Selector="CheckBox:pointerover /template/ Border#PART_Border"> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUncheckedPointerOver}" /> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUncheckedPointerOver}" /> |
</Style> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUncheckedPointerOver}" /> |
|
||||
</Style> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
|
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUncheckedPointerOver}" /> |
||||
<Style Selector="CheckBox:pointerover /template/ Border#NormalRectangle"> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUncheckedPointerOver}" /> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUncheckedPointerOver}" /> |
</Style> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUncheckedPointerOver}" /> |
|
||||
</Style> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUncheckedPointerOver}" /> |
||||
<Style Selector="CheckBox:pointerover /template/ Path#CheckGlyph"> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUncheckedPointerOver}" /> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUncheckedPointerOver}" /> |
</Style> |
||||
</Style> |
|
||||
|
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
<!-- Unchecked Pressed State --> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUncheckedPointerOver}" /> |
||||
<Style Selector="CheckBox:pressed /template/ ContentPresenter#ContentPresenter"> |
</Style> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUncheckedPressed}" /> |
</Style.Children> |
||||
</Style> |
</Style> |
||||
|
|
||||
<Style Selector="CheckBox:pressed /template/ Border#PART_Border"> |
<!-- Unchecked Pressed State --> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUncheckedPressed}" /> |
<Style Selector="^:pressed"> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUncheckedPressed}" /> |
<Style.Children> |
||||
</Style> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUncheckedPressed}" /> |
||||
<Style Selector="CheckBox:pressed /template/ Border#NormalRectangle"> |
</Style> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUncheckedPressed}" /> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUncheckedPressed}" /> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUncheckedPressed}" /> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUncheckedPressed}" /> |
||||
<Style Selector="CheckBox:pressed /template/ Path#CheckGlyph"> |
</Style> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUncheckedPressed}" /> |
|
||||
</Style> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUncheckedPressed}" /> |
||||
<!-- Unchecked Disabled state --> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUncheckedPressed}" /> |
||||
<Style Selector="CheckBox:disabled /template/ ContentPresenter#ContentPresenter"> |
</Style> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUncheckedDisabled}" /> |
|
||||
</Style> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUncheckedPressed}" /> |
||||
<Style Selector="CheckBox:disabled /template/ Border#PART_Border"> |
</Style> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUncheckedDisabled}" /> |
</Style.Children> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUncheckedDisabled}" /> |
</Style> |
||||
</Style> |
|
||||
|
<!-- Unchecked Disabled state --> |
||||
<Style Selector="CheckBox:disabled /template/ Border#NormalRectangle"> |
<Style Selector="^:disabled"> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUncheckedDisabled}" /> |
<Style.Children> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUncheckedDisabled}" /> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
</Style> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundUncheckedDisabled}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:disabled /template/ Path#CheckGlyph"> |
|
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUncheckedDisabled}" /> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundUncheckedDisabled}" /> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushUncheckedDisabled}" /> |
||||
|
</Style> |
||||
<!-- Checked Normal State --> |
|
||||
<Style Selector="CheckBox:checked"> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundChecked}" /> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeUncheckedDisabled}" /> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillUncheckedDisabled}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:checked"> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundChecked}" /> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushChecked}" /> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundUncheckedDisabled}" /> |
||||
</Style> |
</Style> |
||||
|
</Style.Children> |
||||
<Style Selector="CheckBox:checked /template/ Border#NormalRectangle"> |
</Style> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundFillChecked}" /> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillChecked}" /> |
<Style Selector="^:checked"> |
||||
</Style> |
<!-- Checked Normal State --> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundChecked}" /> |
||||
<Style Selector="CheckBox:checked /template/ Path#CheckGlyph"> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundChecked}" /> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundChecked}" /> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushChecked}" /> |
||||
<Setter Property="Data" Value="M1507 31L438 1101L-119 543L-29 453L438 919L1417 -59L1507 31Z" /> |
|
||||
<Setter Property="Width" Value="9" /> |
<Style.Children> |
||||
<Setter Property="Opacity" Value="1" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
<Setter Property="FlowDirection" Value="LeftToRight" /> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundFillChecked}" /> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillChecked}" /> |
||||
|
</Style> |
||||
<!-- Checked PointerOver State --> |
|
||||
<Style Selector="CheckBox:checked:pointerover /template/ ContentPresenter#ContentPresenter"> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundCheckedPointerOver}" /> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundChecked}" /> |
||||
</Style> |
<Setter Property="Data" Value="M1507 31L438 1101L-119 543L-29 453L438 919L1417 -59L1507 31Z" /> |
||||
|
<Setter Property="Width" Value="9" /> |
||||
<Style Selector="CheckBox:checked:pointerover /template/ Border#PART_Border"> |
<Setter Property="Opacity" Value="1" /> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundCheckedPointerOver}" /> |
<Setter Property="FlowDirection" Value="LeftToRight" /> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushCheckedPointerOver}" /> |
</Style> |
||||
</Style> |
|
||||
|
<!-- Checked PointerOver State --> |
||||
<Style Selector="CheckBox:checked:pointerover /template/ Border#NormalRectangle"> |
<Style Selector="^:pointerover"> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeCheckedPointerOver}" /> |
<Style.Children> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillCheckedPointerOver}" /> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
</Style> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundCheckedPointerOver}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:checked:pointerover /template/ Path#CheckGlyph"> |
|
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundCheckedPointerOver}" /> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundCheckedPointerOver}" /> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushCheckedPointerOver}" /> |
||||
<!-- Checked Pressed State --> |
</Style> |
||||
<Style Selector="CheckBox:checked:pressed /template/ ContentPresenter#ContentPresenter"> |
|
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundCheckedPressed}" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
</Style> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeCheckedPointerOver}" /> |
||||
|
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillCheckedPointerOver}" /> |
||||
<Style Selector="CheckBox:checked:pressed /template/ Border#PART_Border"> |
</Style> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundCheckedPressed}" /> |
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushCheckedPressed}" /> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
</Style> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundCheckedPointerOver}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:checked:pressed /template/ Border#NormalRectangle"> |
</Style.Children> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeCheckedPressed}" /> |
</Style> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillCheckedPressed}" /> |
|
||||
</Style> |
<!-- Checked Pressed State --> |
||||
|
<Style Selector="^:pressed"> |
||||
<Style Selector="CheckBox:checked:pressed /template/ Path#CheckGlyph"> |
<Style.Children> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundCheckedPressed}" /> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
</Style> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundCheckedPressed}" /> |
||||
|
</Style> |
||||
<!-- Checked Disabled State --> |
|
||||
<Style Selector="CheckBox:checked:disabled /template/ ContentPresenter#ContentPresenter"> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundCheckedDisabled}" /> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundCheckedPressed}" /> |
||||
</Style> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushCheckedPressed}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:checked:disabled /template/ Border#PART_Border"> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundCheckedDisabled}" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushCheckedDisabled}" /> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeCheckedPressed}" /> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillCheckedPressed}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:checked:disabled /template/ Border#NormalRectangle"> |
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeCheckedDisabled}" /> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillCheckedDisabled}" /> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundCheckedPressed}" /> |
||||
</Style> |
</Style> |
||||
|
</Style.Children> |
||||
<Style Selector="CheckBox:checked:disabled /template/ Path#CheckGlyph"> |
</Style> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundCheckedDisabled}" /> |
|
||||
</Style> |
<!-- Checked Disabled State --> |
||||
|
<Style Selector="^:disabled"> |
||||
|
<Style.Children> |
||||
<!-- Indeterminate Normal State --> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
<Style Selector="CheckBox:indeterminate"> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundCheckedDisabled}" /> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminate}" /> |
</Style> |
||||
</Style> |
|
||||
|
<Style Selector="^ /template/ Border#PART_Border"> |
||||
<Style Selector="CheckBox:indeterminate"> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundCheckedDisabled}" /> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminate}" /> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushCheckedDisabled}" /> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminate}" /> |
</Style> |
||||
</Style> |
|
||||
|
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
<Style Selector="CheckBox:indeterminate /template/ Border#NormalRectangle"> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeCheckedDisabled}" /> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminate}" /> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillCheckedDisabled}" /> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminate}" /> |
</Style> |
||||
</Style> |
|
||||
|
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
<Style Selector="CheckBox:indeterminate /template/ Path#CheckGlyph"> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundCheckedDisabled}" /> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminate}" /> |
</Style> |
||||
<Setter Property="Data" Value="M1536 1536v-1024h-1024v1024h1024z" /> |
</Style.Children> |
||||
<Setter Property="Width" Value="7" /> |
</Style> |
||||
<Setter Property="Opacity" Value="1" /> |
</Style.Children> |
||||
</Style> |
</Style> |
||||
|
|
||||
<!-- Indeterminate PointerOver State --> |
<Style Selector="^:indeterminate"> |
||||
<Style Selector="CheckBox:indeterminate:pointerover /template/ ContentPresenter#ContentPresenter"> |
<!-- Indeterminate Normal State --> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminatePointerOver}" /> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminate}" /> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminate}" /> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminate}" /> |
||||
<Style Selector="CheckBox:indeterminate:pointerover /template/ Border#PART_Border"> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminatePointerOver}" /> |
<Style.Children> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminatePointerOver}" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
</Style> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminate}" /> |
||||
|
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminate}" /> |
||||
<Style Selector="CheckBox:indeterminate:pointerover /template/ Border#NormalRectangle"> |
</Style> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminatePointerOver}" /> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminatePointerOver}" /> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
</Style> |
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminate}" /> |
||||
|
<Setter Property="Data" Value="M1536 1536v-1024h-1024v1024h1024z" /> |
||||
<Style Selector="CheckBox:indeterminate:pointerover /template/ Path#CheckGlyph"> |
<Setter Property="Width" Value="7" /> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminatePointerOver}" /> |
<Setter Property="Opacity" Value="1" /> |
||||
</Style> |
</Style> |
||||
|
|
||||
<!-- Indeterminate Pressed State --> |
<!-- Indeterminate PointerOver State --> |
||||
<Style Selector="CheckBox:indeterminate:pressed /template/ ContentPresenter#ContentPresenter"> |
<Style Selector="^:pointerover"> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminatePressed}" /> |
<Style.Children> |
||||
</Style> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminatePointerOver}" /> |
||||
<Style Selector="CheckBox:indeterminate:pressed /template/ Border#PART_Border"> |
</Style> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminatePressed}" /> |
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminatePressed}" /> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
</Style> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminatePointerOver}" /> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminatePointerOver}" /> |
||||
<Style Selector="CheckBox:indeterminate:pressed /template/ Border#NormalRectangle"> |
</Style> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminatePressed}" /> |
|
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminatePressed}" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
</Style> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminatePointerOver}" /> |
||||
|
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminatePointerOver}" /> |
||||
<Style Selector="CheckBox:indeterminate:pressed /template/ Path#CheckGlyph"> |
</Style> |
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminatePressed}" /> |
|
||||
</Style> |
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminatePointerOver}" /> |
||||
<!-- Indeterminate Disabled State --> |
</Style> |
||||
<Style Selector="CheckBox:indeterminate:disabled /template/ ContentPresenter#ContentPresenter"> |
</Style.Children> |
||||
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminateDisabled}" /> |
</Style> |
||||
</Style> |
|
||||
|
<!-- Indeterminate Pressed State --> |
||||
<Style Selector="CheckBox:indeterminate:disabled /template/ Border#PART_Border"> |
<Style Selector="^:pressed"> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminateDisabled}" /> |
<Style.Children> |
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminateDisabled}" /> |
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
</Style> |
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminatePressed}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:indeterminate:disabled /template/ Border#NormalRectangle"> |
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminateDisabled}" /> |
<Style Selector="^ /template/ Border#PART_Border"> |
||||
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminateDisabled}" /> |
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminatePressed}" /> |
||||
</Style> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminatePressed}" /> |
||||
|
</Style> |
||||
<Style Selector="CheckBox:indeterminate:disabled /template/ Path#CheckGlyph"> |
|
||||
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminateDisabled}" /> |
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
</Style> |
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminatePressed}" /> |
||||
</Styles> |
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminatePressed}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminatePressed}" /> |
||||
|
</Style> |
||||
|
</Style.Children> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- Indeterminate Disabled State --> |
||||
|
<Style Selector="^:disabled"> |
||||
|
<Style.Children> |
||||
|
<Style Selector="^ /template/ ContentPresenter#ContentPresenter"> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource CheckBoxForegroundIndeterminateDisabled}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="^ /template/ Border#PART_Border"> |
||||
|
<Setter Property="Background" Value="{DynamicResource CheckBoxBackgroundIndeterminateDisabled}" /> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxBorderBrushIndeterminateDisabled}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="^ /template/ Border#NormalRectangle"> |
||||
|
<Setter Property="BorderBrush" Value="{DynamicResource CheckBoxCheckBackgroundStrokeIndeterminateDisabled}" /> |
||||
|
<Setter Property="Background" Value="{DynamicResource CheckBoxCheckBackgroundFillIndeterminateDisabled}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<Style Selector="^ /template/ Path#CheckGlyph"> |
||||
|
<Setter Property="Fill" Value="{DynamicResource CheckBoxCheckGlyphForegroundIndeterminateDisabled}" /> |
||||
|
</Style> |
||||
|
</Style.Children> |
||||
|
</Style> |
||||
|
</Style.Children> |
||||
|
</Style> |
||||
|
</Style.Children> |
||||
|
</Style> |
||||
|
|||||
@ -0,0 +1,275 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Styling; |
||||
|
using Avalonia.Styling.Activators; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Avalonia.Base.UnitTests.Styling |
||||
|
{ |
||||
|
public class SelectorTests_Nesting |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Nesting_Class_Doesnt_Match_Parent_OfType_Selector() |
||||
|
{ |
||||
|
var control = new Control2(); |
||||
|
Style nested; |
||||
|
var parent = new Style(x => x.OfType<Control1>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => x.Nesting().Class("foo"))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.NeverThisType, match.Result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Or_Nesting_Class_Doesnt_Match_Parent_OfType_Selector() |
||||
|
{ |
||||
|
var control = new Control2(); |
||||
|
Style nested; |
||||
|
var parent = new Style(x => x.OfType<Control1>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => Selectors.Or( |
||||
|
x.Nesting().Class("foo"), |
||||
|
x.Nesting().Class("bar")))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.NeverThisType, match.Result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Or_Nesting_Child_OfType_Doesnt_Match_Parent_OfType_Selector() |
||||
|
{ |
||||
|
var control = new Control1(); |
||||
|
var panel = new DockPanel { Children = { control } }; |
||||
|
Style nested; |
||||
|
var parent = new Style(x => x.OfType<Panel>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => Selectors.Or( |
||||
|
x.Nesting().Child().OfType<Control1>(), |
||||
|
x.Nesting().Child().OfType<Control1>()))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.NeverThisInstance, match.Result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Double_Nesting_Class_Doesnt_Match_Grandparent_OfType_Selector() |
||||
|
{ |
||||
|
var control = new Control2 |
||||
|
{ |
||||
|
Classes = { "foo", "bar" }, |
||||
|
}; |
||||
|
|
||||
|
Style parent; |
||||
|
Style nested; |
||||
|
var grandparent = new Style(x => x.OfType<Control1>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(parent = new Style(x => x.Nesting().Class("foo")) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => x.Nesting().Class("bar"))) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.NeverThisType, match.Result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Nesting_Class_Matches() |
||||
|
{ |
||||
|
var control = new Control1 { Classes = { "foo" } }; |
||||
|
Style nested; |
||||
|
var parent = new Style(x => x.OfType<Control1>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => x.Nesting().Class("foo"))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.Sometimes, match.Result); |
||||
|
|
||||
|
var sink = new ActivatorSink(match.Activator); |
||||
|
|
||||
|
Assert.True(sink.Active); |
||||
|
control.Classes.Clear(); |
||||
|
Assert.False(sink.Active); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Double_Nesting_Class_Matches() |
||||
|
{ |
||||
|
var control = new Control1 |
||||
|
{ |
||||
|
Classes = { "foo", "bar" }, |
||||
|
}; |
||||
|
|
||||
|
Style parent; |
||||
|
Style nested; |
||||
|
var grandparent = new Style(x => x.OfType<Control1>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(parent = new Style(x => x.Nesting().Class("foo")) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => x.Nesting().Class("bar"))) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.Sometimes, match.Result); |
||||
|
|
||||
|
var sink = new ActivatorSink(match.Activator); |
||||
|
|
||||
|
Assert.True(sink.Active); |
||||
|
control.Classes.Remove("foo"); |
||||
|
Assert.False(sink.Active); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Or_Nesting_Class_Matches() |
||||
|
{ |
||||
|
var control = new Control1 { Classes = { "foo" } }; |
||||
|
Style nested; |
||||
|
var parent = new Style(x => x.OfType<Control1>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => Selectors.Or( |
||||
|
x.Nesting().Class("foo"), |
||||
|
x.Nesting().Class("bar")))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.Sometimes, match.Result); |
||||
|
|
||||
|
var sink = new ActivatorSink(match.Activator); |
||||
|
|
||||
|
Assert.True(sink.Active); |
||||
|
control.Classes.Clear(); |
||||
|
Assert.False(sink.Active); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Or_Nesting_Child_OfType_Matches() |
||||
|
{ |
||||
|
var control = new Control1 { Classes = { "foo" } }; |
||||
|
var panel = new Panel { Children = { control } }; |
||||
|
Style nested; |
||||
|
var parent = new Style(x => x.OfType<Panel>()) |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => Selectors.Or( |
||||
|
x.Nesting().Child().OfType<Control1>(), |
||||
|
x.Nesting().Child().OfType<Control1>()))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var match = nested.Selector.Match(control, parent); |
||||
|
Assert.Equal(SelectorMatchResult.AlwaysThisInstance, match.Result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Nesting_With_No_Parent_Style_Fails() |
||||
|
{ |
||||
|
var control = new Control1(); |
||||
|
var style = new Style(x => x.Nesting().OfType<Control1>()); |
||||
|
|
||||
|
Assert.Throws<InvalidOperationException>(() => style.Selector.Match(control, null)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Nesting_With_No_Parent_Selector_Fails() |
||||
|
{ |
||||
|
var control = new Control1(); |
||||
|
Style nested; |
||||
|
var parent = new Style |
||||
|
{ |
||||
|
Children = |
||||
|
{ |
||||
|
(nested = new Style(x => x.Nesting().Class("foo"))), |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Assert.Throws<InvalidOperationException>(() => nested.Selector.Match(control, parent)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Adding_Child_With_No_Nesting_Selector_Fails() |
||||
|
{ |
||||
|
var parent = new Style(x => x.OfType<Control1>()); |
||||
|
var child = new Style(x => x.Class("foo")); |
||||
|
|
||||
|
Assert.Throws<InvalidOperationException>(() => parent.Children.Add(child)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Adding_Combinator_Selector_Child_With_No_Nesting_Selector_Fails() |
||||
|
{ |
||||
|
var parent = new Style(x => x.OfType<Control1>()); |
||||
|
var child = new Style(x => x.Class("foo").Descendant().Class("bar")); |
||||
|
|
||||
|
Assert.Throws<InvalidOperationException>(() => parent.Children.Add(child)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Adding_Or_Selector_Child_With_No_Nesting_Selector_Fails() |
||||
|
{ |
||||
|
var parent = new Style(x => x.OfType<Control1>()); |
||||
|
var child = new Style(x => Selectors.Or( |
||||
|
x.Nesting().Class("foo"), |
||||
|
x.Class("bar"))); |
||||
|
|
||||
|
Assert.Throws<InvalidOperationException>(() => parent.Children.Add(child)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Can_Add_Child_Without_Nesting_Selector_To_Style_Without_Selector() |
||||
|
{ |
||||
|
var parent = new Style(); |
||||
|
var child = new Style(x => x.Class("foo")); |
||||
|
|
||||
|
parent.Children.Add(child); |
||||
|
} |
||||
|
|
||||
|
public class Control1 : Control |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public class Control2 : Control |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
private class ActivatorSink : IStyleActivatorSink |
||||
|
{ |
||||
|
public ActivatorSink(IStyleActivator source) => source.Subscribe(this); |
||||
|
public bool Active { get; private set; } |
||||
|
public void OnNext(bool value, int tag) => Active = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue