Skip to content

Commit bcc0b84

Browse files
authored
Merge branch 'main' into SizerStyles
2 parents b1a325b + 0bed1b7 commit bcc0b84

File tree

10 files changed

+244
-39
lines changed

10 files changed

+244
-39
lines changed

components/ColorPicker/src/ColorPicker.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace CommunityToolkit.WinUI.Controls;
4242
[TemplatePart(Name = nameof(ColorPicker.CheckeredBackground9Border), Type = typeof(Border))]
4343
[TemplatePart(Name = nameof(ColorPicker.CheckeredBackground10Border), Type = typeof(Border))]
4444
[TemplatePart(Name = nameof(ColorPicker.ColorPanelSelector), Type = typeof(Segmented))]
45+
[TemplatePart(Name = nameof(ColorPicker.ContentContainer), Type = typeof(SwitchPresenter))]
4546
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumControl), Type = typeof(ColorSpectrum))]
4647
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumAlphaSlider), Type = typeof(ColorPickerSlider))]
4748
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumThirdDimensionSlider), Type = typeof(ColorPickerSlider))]
@@ -74,7 +75,9 @@ public partial class ColorPicker : Microsoft.UI.Xaml.Controls.ColorPicker
7475
private Color? updatedRgbColor = null;
7576
private DispatcherQueueTimer? dispatcherQueueTimer = null;
7677

77-
private Segmented ColorPanelSelector;
78+
private Segmented ColorPanelSelector;
79+
private SwitchPresenter ContentContainer;
80+
7881
private ColorSpectrum ColorSpectrumControl;
7982
private ColorPickerSlider ColorSpectrumAlphaSlider;
8083
private ColorPickerSlider ColorSpectrumThirdDimensionSlider;
@@ -177,6 +180,7 @@ protected override void OnApplyTemplate()
177180
this.ConnectEvents(false);
178181

179182
this.ColorPanelSelector = (Segmented)GetTemplateChild(nameof(ColorPanelSelector));
183+
this.ContentContainer = (SwitchPresenter)GetTemplateChild(nameof(ContentContainer));
180184

181185
this.ColorSpectrumControl = (ColorSpectrum)GetTemplateChild(nameof(ColorSpectrumControl));
182186
this.ColorSpectrumAlphaSlider = (ColorPickerSlider)this.GetTemplateChild(nameof(ColorSpectrumAlphaSlider));
@@ -255,6 +259,8 @@ private void ConnectEvents(bool connected)
255259
this.eventsConnected == false)
256260
{
257261
// Add all events
262+
if (this.ColorPanelSelector != null) { this.ColorPanelSelector.SelectionChanged += this.ColorPanelSelector_SelectionChanged; }
263+
258264
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.ColorChanged += ColorSpectrum_ColorChanged; }
259265
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.GotFocus += ColorSpectrum_GotFocus; }
260266
if (this.HexInputTextBox != null) { this.HexInputTextBox.KeyDown += HexInputTextBox_KeyDown; }
@@ -299,6 +305,8 @@ private void ConnectEvents(bool connected)
299305
this.eventsConnected == true)
300306
{
301307
// Remove all events
308+
if (this.ColorPanelSelector != null) { this.ColorPanelSelector.SelectionChanged -= this.ColorPanelSelector_SelectionChanged; }
309+
302310
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.ColorChanged -= ColorSpectrum_ColorChanged; }
303311
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.GotFocus -= ColorSpectrum_GotFocus; }
304312
if (this.HexInputTextBox != null) { this.HexInputTextBox.KeyDown -= HexInputTextBox_KeyDown; }
@@ -1186,6 +1194,22 @@ private void CustomPaletteColors_CollectionChanged(object? sender, NotifyCollect
11861194
return;
11871195
}
11881196

1197+
/// <summary>
1198+
/// Event handler for when the color panel selector selection changes.
1199+
/// We are setting the value here instead of ElementName binding as a workaround for AoT issues.
1200+
/// (See https://github.com/microsoft/microsoft-ui-xaml/issues/10214)
1201+
/// </summary>
1202+
private void ColorPanelSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
1203+
{
1204+
if (this.ContentContainer is null ||
1205+
(sender as Segmented)?.SelectedItem is not FrameworkElement selectedItem)
1206+
{
1207+
return;
1208+
}
1209+
1210+
this.ContentContainer.Value = selectedItem.Name;
1211+
}
1212+
11891213
/// <summary>
11901214
/// Event handler for when the color spectrum color is changed.
11911215
/// This occurs when the user presses on the spectrum to select a new color.

components/ColorPicker/src/ColorPicker.xaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@
237237
</controls:Segmented>
238238

239239
<controls:SwitchPresenter x:Name="ContentContainer"
240-
Grid.Row="2"
241-
Value="{Binding ElementName=ColorPanelSelector, Path=SelectedItem.Name}">
240+
Grid.Row="2">
242241
<controls:Case Value="SpectrumItem">
243242
<Grid HorizontalAlignment="Stretch"
244243
animations:Implicit.HideAnimations="{StaticResource HideTransitions}"

components/Segmented/src/SegmentedItem/SegmentedItem.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
1+
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
22
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
33
xmlns:local="using:CommunityToolkit.WinUI.Controls"
44
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
@@ -614,7 +614,7 @@
614614
<Border x:Name="PART_Hover"
615615
Margin="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource MarginConverter}}"
616616
Background="Transparent"
617-
CornerRadius="2"
617+
CornerRadius="{TemplateBinding CornerRadius}"
618618
RenderTransformOrigin="0.5, 0.5">
619619
<win:Border.BackgroundTransition>
620620
<win:BrushTransition Duration="0:0:0.083" />

components/SettingsControls/samples/Dependencies.props

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,27 @@
99
For UWP / WinAppSDK / Uno packages, place the package references here.
1010
-->
1111
<Project>
12+
<ItemGroup>
13+
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
14+
</ItemGroup>
15+
1216
<!-- WinUI 2 / UWP -->
1317
<ItemGroup Condition="'$(IsUwp)' == 'true'">
14-
<!-- <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.2"/> -->
18+
<PackageReference Include="Microsoft.Xaml.Behaviors.Uwp.Managed" Version="3.0.0"/>
1519
</ItemGroup>
1620

1721
<!-- WinUI 2 / Uno -->
1822
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '2'">
19-
<!-- <PackageReference Include="Uno.Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.11"/> -->
23+
<PackageReference Include="Uno.Microsoft.Xaml.Behaviors.Interactivity" Version="3.0.3"/>
2024
</ItemGroup>
2125

2226
<!-- WinUI 3 / WinAppSdk -->
23-
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
24-
<!-- <PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.2"/> -->
27+
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
28+
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.0"/>
2529
</ItemGroup>
2630

2731
<!-- WinUI 3 / Uno -->
2832
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '3'">
29-
<!-- <PackageReference Include="Uno.CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.100-dev.15.g12261e2626"/> -->
33+
<PackageReference Include="Uno.Microsoft.Xaml.Behaviors.Interactivity.WinUI" Version="3.0.3"/>
3034
</ItemGroup>
3135
</Project>

components/SettingsControls/samples/SettingsCard.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,9 @@ You can set the `Header`, `Description`, `HeaderIcon` and `Content` properties t
2020
SettingsCard can also be turned into a button, by setting the `IsClickEnabled` property. This can be useful whenever you want your settings component to navigate to a detail page or open an external link. You can set a custom icon by setting the `ActionIcon`, or hiding it completely by setting the `IsActionIconVisible` to `false`.
2121

2222
> [!SAMPLE ClickableSettingsCardSample]
23+
24+
### Settings page example
25+
26+
The following sample provides a typical design page, following the correct Windows 11 design specifications for things like spacing, section headers and animations.
27+
28+
> [!SAMPLE SettingsPageExample]

components/SettingsControls/samples/SettingsControls.Samples.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
<PropertyGroup>
55
<ToolkitComponentName>SettingsControls</ToolkitComponentName>
6+
<LangVersion>preview</LangVersion>
67
</PropertyGroup>
78

89
<!-- Sets this up as a toolkit component's sample project -->

components/SettingsControls/samples/SettingsExpander.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,29 @@ 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+
6. Optionally, add a behavior to highlight the drag region when the pointer is over it.
49+
50+
Note: If controls within the dragged SettingsCard/Expander state are not bound, they will be reset upon drop in some cases. E.g. a ToggleSwitch. It is best to ensure you have bound your control's states to your data model.
51+
2952
### Settings page example
3053

3154
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: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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:Interactivity="using:Microsoft.Xaml.Interactivity"
5+
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:local="using:SettingsControlsExperiment.Samples"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
mc:Ignorable="d">
10+
11+
<!--
12+
Enabled the List view to drag its items and reorder them around,
13+
plus need SelectionMode None so the indicator doesn't appear when clicking on the drag region
14+
-->
15+
<ListView AllowDrop="True"
16+
CanDragItems="True"
17+
CanReorderItems="True"
18+
ItemsSource="{x:Bind MyDataSet}"
19+
SelectionMode="None">
20+
<ListView.ItemTemplate>
21+
<DataTemplate x:DataType="local:ExpandedCardInfo">
22+
<Grid>
23+
<Grid.ColumnDefinitions>
24+
<ColumnDefinition Width="Auto" />
25+
<ColumnDefinition Width="*" />
26+
</Grid.ColumnDefinitions>
27+
<!-- Provide a custom area that can be manipulated by the user, this could be before or after the card. -->
28+
<Border Width="36"
29+
Height="75"
30+
Margin="1,1,1,1"
31+
VerticalAlignment="Top"
32+
Background="Transparent"
33+
CornerRadius="{ThemeResource ControlCornerRadius}">
34+
<TextBlock HorizontalAlignment="Center"
35+
VerticalAlignment="Center"
36+
FontFamily="Segoe UI Symbol"
37+
FontSize="20"
38+
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
39+
Text="&#x283F;" />
40+
<!-- Use Behaviors to hover on pointer -->
41+
<Interactivity:Interaction.Behaviors>
42+
<Interactivity:EventTriggerBehavior EventName="PointerEntered">
43+
<Interactivity:ChangePropertyAction PropertyName="Background">
44+
<Interactivity:ChangePropertyAction.Value>
45+
<SolidColorBrush Color="{ThemeResource ControlFillColorDefault}" />
46+
</Interactivity:ChangePropertyAction.Value>
47+
</Interactivity:ChangePropertyAction>
48+
</Interactivity:EventTriggerBehavior>
49+
<Interactivity:EventTriggerBehavior EventName="PointerExited">
50+
<Interactivity:ChangePropertyAction PropertyName="Background">
51+
<Interactivity:ChangePropertyAction.Value>
52+
<SolidColorBrush Color="Transparent" />
53+
</Interactivity:ChangePropertyAction.Value>
54+
</Interactivity:ChangePropertyAction>
55+
</Interactivity:EventTriggerBehavior>
56+
</Interactivity:Interaction.Behaviors>
57+
</Border>
58+
<!-- Standard Settings Expander (could also just be a Card) -->
59+
<controls:SettingsExpander Grid.Column="1"
60+
Description="{x:Bind Info}"
61+
Header="{x:Bind Name}"
62+
IsExpanded="{x:Bind IsExpanded, Mode=TwoWay}">
63+
64+
<ToggleSwitch IsOn="{x:Bind IsExpanded, Mode=TwoWay}"
65+
OffContent="Off"
66+
OnContent="On" />
67+
68+
<controls:SettingsExpander.Items>
69+
<controls:SettingsCard Header="{x:Bind LinkDescription}">
70+
<HyperlinkButton Content="{x:Bind Url}"
71+
NavigateUri="{x:Bind Url}" />
72+
</controls:SettingsCard>
73+
</controls:SettingsExpander.Items>
74+
</controls:SettingsExpander>
75+
</Grid>
76+
</DataTemplate>
77+
</ListView.ItemTemplate>
78+
<!-- Customize Size of Item Container from ListView -->
79+
<ListView.ItemContainerStyle>
80+
<Style BasedOn="{StaticResource DefaultListViewItemStyle}"
81+
TargetType="ListViewItem">
82+
<Setter Property="Margin" Value="0" />
83+
<Setter Property="Padding" Value="4" />
84+
</Style>
85+
</ListView.ItemContainerStyle>
86+
<!-- Hides the overall highlight from the ListView Container -->
87+
<ListView.Resources>
88+
<SolidColorBrush x:Key="ListViewItemBackgroundPointerOver"
89+
Color="Transparent" />
90+
</ListView.Resources>
91+
</ListView>
92+
</Page>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
using CommunityToolkit.Mvvm.ComponentModel;
6+
7+
namespace SettingsControlsExperiment.Samples;
8+
9+
[ToolkitSample(id: nameof(SettingsExpanderDragHandleSample), "SettingsExpanderDragHandle", description: "The SettingsCard/SettingsExpander can be within a collection itself which can be re-ordered.")]
10+
public sealed partial class SettingsExpanderDragHandleSample : Page
11+
{
12+
13+
public ObservableCollection<ExpandedCardInfo> MyDataSet = new() {
14+
new()
15+
{
16+
Name = "First Item",
17+
Info = "More about first item.",
18+
LinkDescription = "Click the link for more on first item.",
19+
Url = "https://microsoft.com/",
20+
},
21+
new()
22+
{
23+
Name = "Second Item",
24+
Info = "More about second item.",
25+
LinkDescription = "Click the link for more on second item.",
26+
Url = "https://xbox.com/",
27+
},
28+
new()
29+
{
30+
Name = "Third Item",
31+
Info = "More about third item.",
32+
LinkDescription = "Click the link for more on third item.",
33+
Url = "https://toolkitlabs.dev/",
34+
},
35+
};
36+
37+
public SettingsExpanderDragHandleSample()
38+
{
39+
this.InitializeComponent();
40+
}
41+
}
42+
43+
public partial class ExpandedCardInfo : ObservableObject
44+
{
45+
public string? Name { get; set; }
46+
47+
public string? Info { get; set; }
48+
49+
public string? LinkDescription { get; set; }
50+
51+
public string? Url { get; set; }
52+
53+
[ObservableProperty]
54+
public partial bool IsExpanded { get; set; } = false;
55+
}
56+

0 commit comments

Comments
 (0)