Skip to content
Merged
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
4 changes: 2 additions & 2 deletions samples/SampleApp/DemoPages/GroupedTileListBoxDemo.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@
<TextBlock TextWrapping="Wrap" Foreground="{DynamicResource TextControlPlaceholderForeground}">
SelectionMode="Multiple" with SelectedItems bound two-way.
Pointer: click replaces, Ctrl/Cmd+click toggles, Shift+click selects a range.
Drag on empty space to marquee-select (Ctrl/Cmd+drag adds to the selection); drag past the top/bottom edge to auto-scroll.
Comment thread
xfortin-devolutions marked this conversation as resolved.
Keyboard: arrows move, Shift+arrows extend the range, Ctrl/Cmd+Space toggles the current tile, Ctrl/Cmd+A selects all.
</TextBlock>

Expand Down Expand Up @@ -344,11 +345,10 @@
<!-- Resizable Grid -->
<Grid Height="400" ColumnDefinitions="2*,Auto,*">
<GroupedTileListBox Grid.Column="0"
ItemsSource="{Binding GroupedItems}"
ItemsSource="{Binding MultiSelectGroupedItems}"
Comment thread
rbstp marked this conversation as resolved.
SelectionMode="Multiple"
SelectedItems="{Binding MultiSelectedItems}"
GroupSelector="{Binding CategoryGroupSelector}"
GroupOrderSelector="{Binding CategoryGroupOrderSelector}"
GroupOrderAlphabetical="True"
ItemWidth="120"
ItemHeight="100"
Expand Down
32 changes: 32 additions & 0 deletions samples/SampleApp/ViewModels/GroupedTileListBoxViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,38 @@ private void SelectLargeAtTarget()
// the control mutates this collection directly and the demo observes it live.
public AvaloniaList<FoodItem> MultiSelectedItems { get; } = new();

// Scenario 5 source. Deliberately large and multi-grouped (many groups, many items per group,
// uneven counts so last rows are partial) so marquee drag-selection, cross-group rectangles, and
// edge auto-scroll can all be exercised. Kept separate from GroupedItems so Scenario 1 is unaffected.
public List<FoodItem> MultiSelectGroupedItems { get; } = GenerateMultiSelectItems();

private static List<FoodItem> GenerateMultiSelectItems()
{
// (group label, item count) — varied counts on purpose to produce partial last rows.
(string Group, int Count)[] groups =
{
("Group A", 42),
("Group B", 55),
("Group C", 63),
("Group D", 48),
("Group E", 70),
("Group F", 39),
("Group G", 58),
("Group H", 51),
};

var items = new List<FoodItem>();
foreach ((string group, int count) in groups)
{
for (int i = 1; i <= count; i++)
{
items.Add(new FoodItem($"{group} · {i:D2}", group));
}
}

return items;
}

// Scenario 1: Named groups
public List<FoodItem> GroupedItems { get; } = new()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<!-- Marquee (drag-to-select rectangle) brushes. Accent-tinted to match the Explorer-style
rubber-band; theme-aware via SystemAccentColor, so no per-theme override is required. -->
<SolidColorBrush x:Key="GroupedTileListBoxSelectionRectangleFill"
Color="{DynamicResource SystemAccentColor}" Opacity="0.2" />
<SolidColorBrush x:Key="GroupedTileListBoxSelectionRectangleBorderBrush"
Color="{DynamicResource SystemAccentColor}" Opacity="0.8" />

<ControlTheme x:Key="{x:Type GroupedTileListBox}" TargetType="GroupedTileListBox">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="4" />
Expand Down Expand Up @@ -29,10 +36,25 @@
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
ClipToBounds="True">
<ScrollViewer Name="PART_ScrollViewer"
Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto" />
<Panel>
<ScrollViewer Name="PART_ScrollViewer"
Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto" />
<!--
Marquee overlay. Shares the ScrollViewer's origin so a pointer
position relative to PART_ScrollViewer maps directly onto this Canvas
(viewport space) and onto content space (viewport + Offset). It never
scrolls with content and never intercepts pointer input.
-->
<Canvas Name="PART_SelectionLayer" IsHitTestVisible="False">
<Border Name="PART_SelectionRectangle"
IsVisible="False"
BorderThickness="1"
Background="{DynamicResource GroupedTileListBoxSelectionRectangleFill}"
BorderBrush="{DynamicResource GroupedTileListBoxSelectionRectangleBorderBrush}" />
</Canvas>
</Panel>
</Border>
</Panel>
</ControlTemplate>
Expand Down
Loading