Skip to content

Commit 2c53e77

Browse files
michael-hawkerArlodotexe
authored andcommitted
Initial example of how to have draggable settings cards/expanders
TODO: Highlight gripper on hover and get Niels once over/opinion
1 parent bd8102b commit 2c53e77

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

components/SettingsControls/samples/SettingsExpander.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ You can easily override certain properties to create custom experiences. For ins
2626
2727
NOTE: Due to [a bug](https://github.com/microsoft/microsoft-ui-xaml/issues/3842) related to the `ItemsRepeater` used in `SettingsExpander`, there might be visual glitches whenever the `SettingsExpander` expands and a `MaxWidth` is set on a parent `StackPanel`. As a workaround, the `StackPanel` (that has the `MaxWidth` set) can be wrapped in a `Grid` to overcome this issue. See the `SettingsPageExample` for snippet.
2828

29+
### Dragging Settings Cards
30+
31+
You may use a list of `SettingsCard` or `SettingsExpander` to represent configurable items within a tool. The order of these may be something you want to track.
32+
33+
In this case there is a conflict between the interactions with the settings card and the drag and drop interactions of a parent containing `ListView`, for instance.
34+
35+
Therefore, it is recommended to use the drag-handle type UI approach for this scenario in having a dedicated space for re-ordering manipulation vs. interaction with the Settings control.
36+
37+
You can see how to do this with `SettingsExpander` in the example below, however it equally works with a collection of `SettingsCard` as the main data template component as well.
38+
39+
> [!SAMPLE SettingsExpanderDragHandleSample]
40+
41+
The main important pieces of this example are:
42+
43+
1. Enabling the three drag properties on the `ListView`: `CanDragItems`, `CanReorderItems`, and `AllowDrop`.
44+
2. Setting `SelectionMode` to `None` to prevent selection and the selection indicator from appearing.
45+
3. Using a simple UIElement to act as a drag handle, the pass-through of the mouse on this element to `ListView` allows the normal drag experience to work uninterrupted.
46+
4. Modifying the `Margin` and `Padding` values of the `ItemContainerStyle` to align cards how we want within the ListView.
47+
5. Overriding the `ListViewItemBackgroundPointerOver` resource to prevent the hover effect across the entire list item, the Settings Controls already have an effect here on hover.
48+
2949
### Settings page example
3050

3151
The following sample provides a typical design page, following the correct Windows 11 design specifications for things like spacing, section headers and animations.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<Page x:Class="SettingsControlsExperiment.Samples.SettingsExpanderDragHandleSample"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:local="using:SettingsControlsExperiment.Samples"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
mc:Ignorable="d">
9+
10+
<!--
11+
Enabled the List view to drag its items and reorder them around,
12+
plus need SelectionMode None so the indicator doesn't appear when clicking on the drag region
13+
-->
14+
<ListView AllowDrop="True"
15+
CanDragItems="True"
16+
CanReorderItems="True"
17+
ItemsSource="{x:Bind MyDataSet}"
18+
SelectionMode="None">
19+
<ListView.ItemTemplate>
20+
<DataTemplate x:DataType="local:ExpandedCardInfo">
21+
<Grid>
22+
<Grid.ColumnDefinitions>
23+
<ColumnDefinition Width="Auto" />
24+
<ColumnDefinition Width="*" />
25+
</Grid.ColumnDefinitions>
26+
<!-- Provide a custom area that can be manipulated by the user -->
27+
<!-- TODO: Show how to highlight this on hover with a behavior -->
28+
<Border Width="18"
29+
Margin="1,1,0,1"
30+
Padding="0"
31+
VerticalAlignment="Stretch"
32+
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
33+
CornerRadius="{ThemeResource ControlCornerRadius}">
34+
<TextBlock HorizontalAlignment="Center"
35+
VerticalAlignment="Center"
36+
FontFamily="Segoe UI Symbol"
37+
FontSize="16"
38+
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
39+
Opacity="0.5"
40+
Text="&#x283F;" />
41+
</Border>
42+
<controls:SettingsExpander Grid.Column="1"
43+
Description="{x:Bind Info}"
44+
Header="{x:Bind Name}">
45+
46+
<ToggleSwitch OffContent="Off"
47+
OnContent="On" />
48+
49+
<controls:SettingsExpander.Items>
50+
<controls:SettingsCard Header="{x:Bind LinkDescription}">
51+
<HyperlinkButton Content="{x:Bind Url}"
52+
NavigateUri="{x:Bind Url}" />
53+
</controls:SettingsCard>
54+
</controls:SettingsExpander.Items>
55+
</controls:SettingsExpander>
56+
</Grid>
57+
</DataTemplate>
58+
</ListView.ItemTemplate>
59+
<ListView.ItemContainerStyle>
60+
<Style BasedOn="{StaticResource DefaultListViewItemStyle}"
61+
TargetType="ListViewItem">
62+
<Setter Property="Margin" Value="0" />
63+
<Setter Property="Padding" Value="4" />
64+
</Style>
65+
</ListView.ItemContainerStyle>
66+
<!-- Hides the overall highlight from the ListView Container -->
67+
<ListView.Resources>
68+
<SolidColorBrush x:Key="ListViewItemBackgroundPointerOver"
69+
Color="Transparent" />
70+
</ListView.Resources>
71+
</ListView>
72+
</Page>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace SettingsControlsExperiment.Samples;
6+
7+
[ToolkitSample(id: nameof(SettingsExpanderDragHandleSample), "SettingsExpanderDragHandle", description: "The SettingsCard/SettingsExpander can be within a collection itself which can be re-ordered.")]
8+
public sealed partial class SettingsExpanderDragHandleSample : Page
9+
{
10+
11+
public ObservableCollection<ExpandedCardInfo> MyDataSet = new() {
12+
new()
13+
{
14+
Name = "First Item",
15+
Info = "More about first item.",
16+
LinkDescription = "Click the link for more on first item.",
17+
Url = "https://microsoft.com/",
18+
},
19+
new()
20+
{
21+
Name = "Second Item",
22+
Info = "More about second item.",
23+
LinkDescription = "Click the link for more on second item.",
24+
Url = "https://xbox.com/",
25+
},
26+
new()
27+
{
28+
Name = "Third Item",
29+
Info = "More about third item.",
30+
LinkDescription = "Click the link for more on third item.",
31+
Url = "https://toolkitlabs.dev/",
32+
},
33+
};
34+
35+
public SettingsExpanderDragHandleSample()
36+
{
37+
this.InitializeComponent();
38+
}
39+
}
40+
41+
public class ExpandedCardInfo
42+
{
43+
public string? Name { get; set; }
44+
45+
public string? Info { get; set; }
46+
47+
public string? LinkDescription { get; set; }
48+
49+
public string? Url { get; set; }
50+
}
51+

0 commit comments

Comments
 (0)