Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions samples/ControlCatalog/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<ResourceDictionary>
<!-- Custom controls defined in other assemblies -->
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://ControlCatalog/ScrollPage.xaml"/>
<ResourceInclude Source="avares://ControlCatalog/NavHeaderItem.xaml"/>
<ResourceInclude Source="avares://ControlCatalog/CustomThemes.xaml"/>
<ResourceInclude Source="avares://ControlCatalog/WindowDrawnDecorations.xaml"/>
</ResourceDictionary.MergedDictionaries>

<!-- Resources used only in the control catalog -->
Expand All @@ -28,6 +28,9 @@
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

<StreamGeometry x:Key="SearchIcon">M10 2.5a7.5 7.5 0 0 1 5.964 12.048l4.743 4.745a1 1 0 0 1-1.32 1.497l-.094-.083-4.745-4.743A7.5 7.5 0 1 1 10 2.5Zm0 2a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11Z</StreamGeometry>
<StreamGeometry x:Key="AppIcon">M24 0C37.2548 0 48 10.7452 48 24V42C48 45.3137 45.3137 48 42 48H24C10.7452 48 0 37.2548 0 24C0 10.7452 10.7452 0 24 0ZM24 7C16.3489 7 9.87832 12.0545 7.74496 19.0065C10.3931 19.1342 12.5 21.321 12.5 24C12.5 26.6793 10.3926 28.8664 7.74496 28.9941C9.83517 35.8054 16.0901 40.7958 23.5395 40.9939C26.6226 40.9252 29.1092 40.2605 31 39V41H41V24C41 14.827 33.7348 7.35088 24.6446 7.012L24.323 7.00301L24 7ZM24 16C28.4183 16 32 19.5817 32 24C32 28.4183 28.4183 32 24 32C19.5817 32 16 28.4183 16 24C16 19.5817 19.5817 16 24 16ZM7.5 20.5C5.567 20.5 4 22.067 4 24C4 25.933 5.567 27.5 7.5 27.5C9.433 27.5 11 25.933 11 24C11 22.067 9.433 20.5 7.5 20.5Z</StreamGeometry>

<!-- Styles attached dynamically depending on current theme (simple or fluent) -->
<FluentTheme x:Key="FluentTheme" />
<SimpleTheme x:Key="SimpleTheme" />
Expand Down
103 changes: 103 additions & 0 deletions samples/ControlCatalog/Controls/HomeItemExpander.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;

namespace ControlCatalog.Controls
{
public class HomeItemExpander : Expander, ISelectable
{
/// <summary>
/// Defines the <see cref="Command"/> property.
/// </summary>
public static readonly StyledProperty<ICommand?> CommandProperty =
Button.CommandProperty.AddOwner<HomeItemExpander>();

/// <summary>
/// Defines the <see cref="CommandParameter"/> property.
/// </summary>
public static readonly StyledProperty<object?> CommandParameterProperty =
Button.CommandParameterProperty.AddOwner<HomeItemExpander>();

/// <summary>
/// Defines the <see cref="CanExpand"/> property.
/// </summary>
public static readonly StyledProperty<bool> CanExpandProperty =
AvaloniaProperty.Register<HomeItemExpander, bool>(
nameof(CanExpand),
defaultBindingMode: BindingMode.TwoWay);

/// <summary>
/// Defines the <see cref="CanExpand"/> property.
/// </summary>
public static readonly DirectProperty<HomeItemExpander, bool> IsEffectivelyExpandedProperty =
AvaloniaProperty.RegisterDirect<HomeItemExpander, bool>(
nameof(IsEffectivelyExpanded),
x => x.IsEffectivelyExpanded,
(x, o) => x.IsEffectivelyExpanded = o,
defaultBindingMode: BindingMode.TwoWay);

/// <summary>
/// Defines the <see cref="IsSelected"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsSelectedProperty =
SelectingItemsControl.IsSelectedProperty.AddOwner<HomeItemExpander>();

/// <summary>
/// Gets or sets an <see cref="ICommand"/> to be invoked when the button is clicked.
/// </summary>
public ICommand? Command
{
get => GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}

/// <summary>
/// Gets or sets a parameter to be passed to the <see cref="Command"/>.
/// </summary>
public object? CommandParameter
{
get => GetValue(CommandParameterProperty);
set => SetValue(CommandParameterProperty, value);
}

/// <summary>
/// Gets or sets a value indicating whether the <see cref="HomeItemExpander"/>
/// content area is open and visible.
/// </summary>
public bool CanExpand
{
get => GetValue(CanExpandProperty);
set => SetValue(CanExpandProperty, value);
}

/// <summary>
/// Gets or sets the selection state of the item.
/// </summary>
public bool IsSelected
{
get => GetValue(IsSelectedProperty);
set => SetValue(IsSelectedProperty, value);
}

/// <summary>
/// Gets whether the <see cref="HomeItemExpander"/> is expanded
/// </summary>
public bool IsEffectivelyExpanded
{
get => field;
private set => SetAndRaise(IsEffectivelyExpandedProperty, ref field, value);
}

protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);

if (change.Property == CanExpandProperty || change.Property == IsExpandedProperty)
{
IsEffectivelyExpanded = CanExpand && IsExpanded;
}
}
}
}
52 changes: 52 additions & 0 deletions samples/ControlCatalog/Controls/SectionControl.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:models="clr-namespace:ControlCatalog.Models"
xmlns:controlCatalog="using:ControlCatalog"
xmlns:viewModels="using:ControlCatalog.ViewModels"
x:DataType="models:HomeSection"
x:Class="ControlCatalog.Controls.SectionControl">
<StackPanel Margin="0,0,0,26">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid RowSpacing="12" ColumnSpacing="12"
Margin="0, 0, 1, 0"
SizeChanged="UniformGrid_OnSizeChanged" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="models:PageItem">
<Button Theme="{StaticResource ButtonCardTheme}"
Command="{Binding $parent[controlCatalog:MainView].((viewModels:MainWindowViewModel)DataContext).NavigateToPageCommand}"
CommandParameter="{Binding}">
<StackPanel Spacing="10">
<Border Background="{DynamicResource HomeBadgeBackground}"
CornerRadius="8"
Width="36" Height="36"
HorizontalAlignment="Left">
<PathIcon Data="{Binding IconData}"
Foreground="{DynamicResource HomeBadgeForeground}"
Width="18" Height="18"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<StackPanel Spacing="3">
<TextBlock Text="{Binding Header}"
FontSize="14" FontWeight="SemiBold" />
<TextBlock Text="{Binding Description}"
FontSize="12"
Foreground="{DynamicResource HomeSubtleForeground}"
TextWrapping="Wrap"
TextTrimming="CharacterEllipsis"
MaxLines="2" />
</StackPanel>
</StackPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</UserControl>
25 changes: 25 additions & 0 deletions samples/ControlCatalog/Controls/SectionControl.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;

namespace ControlCatalog.Controls
{
public partial class SectionControl : UserControl
{
public SectionControl()
{
InitializeComponent();
}

private void UniformGrid_OnSizeChanged(object? sender, SizeChangedEventArgs e)
{
if (sender is not UniformGrid grid)
return;

const int minItemWidth = 248;
grid.Columns = Math.Max(
1,
(int)((e.NewSize.Width + grid.ColumnSpacing) / (minItemWidth + grid.ColumnSpacing)));
}
}
}
79 changes: 79 additions & 0 deletions samples/ControlCatalog/Controls/SelectableButton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Interactivity;

namespace ControlCatalog.Controls
{
[PseudoClasses(":selected")]
public class SelectableButton : ToggleButton, ISelectable
{
/// <summary>
/// Defines the <see cref="IsSelected"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsSelectedProperty =
AvaloniaProperty.Register<SelectableButton, bool>(nameof(IsSelected), false,
defaultBindingMode: BindingMode.TwoWay);

/// <summary>
/// Defines the <see cref="IsSelectedChanged"/> event.
/// </summary>
public static readonly RoutedEvent<RoutedEventArgs> IsSelectedChangedEvent =
RoutedEvent.Register<SelectableButton, RoutedEventArgs>(
nameof(IsSelectedChanged),
RoutingStrategies.Bubble);

public SelectableButton()
{
UpdatePseudoClasses(IsSelected);
}

/// <summary>
/// Gets or sets whether the <see cref="SelectableButton"/> is selected.
/// </summary>
public bool IsSelected
{
get => GetValue(IsSelectedProperty);
set => SetValue(IsSelectedProperty, value);
}

/// <summary>
/// Raised when the <see cref="IsSelected"/> property value changes.
/// </summary>
public event EventHandler<RoutedEventArgs>? IsSelectedChanged
{
add => AddHandler(IsSelectedChangedEvent, value);
remove => RemoveHandler(IsSelectedChangedEvent, value);
}

/// <inheritdoc/>
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);

if (change.Property == IsSelectedProperty)
{
var newValue = change.GetNewValue<bool>();
UpdatePseudoClasses(newValue);
OnIsSelectedChanged(new RoutedEventArgs(IsSelectedChangedEvent));
}
}

private void UpdatePseudoClasses(bool isSelected)
{
PseudoClasses.Set(":selected", isSelected);
}

/// <summary>
/// Called when <see cref="IsSelected"/> changes.
/// </summary>
/// <param name="e">Event arguments for the routed event that is raised by the default implementation of this method.</param>
protected virtual void OnIsSelectedChanged(RoutedEventArgs e)
{
RaiseEvent(e);
}
}
}
Loading