Removing SettingsControls
This commit is contained in:
Родитель
1761f828e0
Коммит
4ffba11bee
|
@ -1,3 +0,0 @@
|
|||
@ECHO OFF
|
||||
|
||||
powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %*
|
Двоичные данные
components/SettingsControls/samples/Assets/SettingsCard.png
Двоичные данные
components/SettingsControls/samples/Assets/SettingsCard.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 3.8 KiB |
Двоичные данные
components/SettingsControls/samples/Assets/SettingsExpander.png
Двоичные данные
components/SettingsControls/samples/Assets/SettingsExpander.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 3.8 KiB |
|
@ -1,42 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<Page x:Class="SettingsControlsExperiment.Samples.ClickableSettingsCardSample"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel Spacing="3">
|
||||
|
||||
<labs:SettingsCard x:Name="settingsCard"
|
||||
Description="A SettingsCard can be made clickable and you can leverage the Command property or Click event."
|
||||
Header="A clickable SettingsCard"
|
||||
IsClickEnabled="True"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard ActionIconToolTip="Open in new window"
|
||||
Description="You can customize the ActionIcon and ActionIconToolTip."
|
||||
Header="Customizing the ActionIcon"
|
||||
IsClickEnabled="True"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<labs:SettingsCard.ActionIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.ActionIcon>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard Header="Hiding the ActionIcon"
|
||||
IsActionIconVisible="False"
|
||||
IsClickEnabled="True"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
</labs:SettingsCard>
|
||||
</StackPanel>
|
||||
</Page>
|
|
@ -1,23 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace SettingsControlsExperiment.Samples;
|
||||
|
||||
[ToolkitSampleBoolOption("IsCardEnabled", true, Title = "Is Enabled")]
|
||||
|
||||
[ToolkitSample(id: nameof(ClickableSettingsCardSample), "ClickableSettingsCardSample", description: "A sample for showing how SettingsCard can be static or clickable.")]
|
||||
public sealed partial class ClickableSettingsCardSample : Page
|
||||
{
|
||||
public ClickableSettingsCardSample()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private async void OnCardClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Windows.System.Launcher.LaunchUriAsync(new Uri("https://www.microsoft.com"));
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<!--
|
||||
WinUI 2 under UWP uses TargetFramework uap10.0.*
|
||||
WinUI 3 under WinAppSdk uses TargetFramework net6.0-windows10.*
|
||||
However, under Uno-powered platforms, both WinUI 2 and 3 can share the same TargetFramework.
|
||||
|
||||
MSBuild doesn't play nicely with this out of the box, so we've made it easy for you.
|
||||
|
||||
For .NET Standard packages, you can use the Nuget Package Manager in Visual Studio.
|
||||
For UWP / WinAppSDK / Uno packages, place the package references here.
|
||||
-->
|
||||
<Project>
|
||||
<!-- WinUI 2 / UWP -->
|
||||
<ItemGroup Condition="'$(IsUwp)' == 'true'">
|
||||
<!-- <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.2"/> -->
|
||||
</ItemGroup>
|
||||
|
||||
<!-- WinUI 2 / Uno -->
|
||||
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '2'">
|
||||
<!-- <PackageReference Include="Uno.Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.11"/> -->
|
||||
</ItemGroup>
|
||||
|
||||
<!-- WinUI 3 / WinAppSdk -->
|
||||
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
|
||||
<!-- <PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.2"/> -->
|
||||
</ItemGroup>
|
||||
|
||||
<!-- WinUI 3 / Uno -->
|
||||
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '3'">
|
||||
<!-- <PackageReference Include="Uno.CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.100-dev.15.g12261e2626"/> -->
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
title: SettingsCard
|
||||
author: niels9001
|
||||
description: A card control that can be used to create Windows 11 style settings experiences.
|
||||
keywords: SettingsCard, Control, Layout, Settings
|
||||
dev_langs:
|
||||
- csharp
|
||||
category: Controls
|
||||
subcategory: Layout
|
||||
discussion-id: 129
|
||||
issue-id: 216
|
||||
icon: Assets/SettingsCard.png
|
||||
---
|
||||
|
||||
SettingsCard is a control that can be used to display settings in your experience. It uses the default styling found in Windows 11 and is easy to use, meets all accesibility standards and will make your settings page look great!
|
||||
You can set the `Header`, `Description`, `HeaderIcon` and `Content` properties to create an easy to use experience, like so:
|
||||
|
||||
> [!SAMPLE SettingsCardSample]
|
||||
|
||||
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`.
|
||||
|
||||
> [!SAMPLE ClickableSettingsCardSample]
|
|
@ -1,57 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<Page x:Class="SettingsControlsExperiment.Samples.SettingsCardSample"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel Spacing="3">
|
||||
<labs:SettingsCard x:Name="settingsCard"
|
||||
Description="This is a default card, with the Header, HeaderIcon, Description and Content set."
|
||||
Header="This is the Header"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<ComboBox SelectedIndex="0">
|
||||
<ComboBoxItem>Option 1</ComboBoxItem>
|
||||
<ComboBoxItem>Option 2</ComboBoxItem>
|
||||
<ComboBoxItem>Option 3</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard Description="You can use a FontIcon, SymbolIcon or BitmapIcon to set the cards HeaderIcon."
|
||||
Header="Icon options"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<BitmapIcon ShowAsMonochrome="False"
|
||||
UriSource="ms-appx:///Assets/AppTitleBar.scale-200.png" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard Header="A card with custom objects as its Description"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.Description>
|
||||
<HyperlinkButton Content="Learn more about Phone Link" />
|
||||
</labs:SettingsCard.Description>
|
||||
<Button Content="Open Phone Link"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard Description="When resizing a SettingsCard, the Content will wrap vertically. You can override this breakpoint by setting the SettingsCardWrapThreshold resource. For edge cases, you can also hide the icon by setting SettingsCardWrapNoIconThreshold."
|
||||
Header="Adaptive layouts"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<labs:SettingsCard.Resources>
|
||||
<x:Double x:Key="SettingsCardWrapThreshold">800</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapNoIconThreshold">600</x:Double>
|
||||
</labs:SettingsCard.Resources>
|
||||
<Button Content="This control will wrap vertically!"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</labs:SettingsCard>
|
||||
</StackPanel>
|
||||
</Page>
|
|
@ -1,16 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace SettingsControlsExperiment.Samples;
|
||||
|
||||
[ToolkitSampleBoolOption("IsCardEnabled", true, Title = "Is Enabled")]
|
||||
|
||||
[ToolkitSample(id: nameof(SettingsCardSample), "SettingsCard", description: "A sample for showing how SettingsCard can be static or clickable.")]
|
||||
public sealed partial class SettingsCardSample : Page
|
||||
{
|
||||
public SettingsCardSample()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<Project Sdk="MSBuild.Sdk.Extras/3.0.23">
|
||||
<PropertyGroup>
|
||||
<ToolkitComponentName>SettingsControls</ToolkitComponentName>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Sets this up as a toolkit component's sample project -->
|
||||
<Import Project="$(ToolingDirectory)\ToolkitComponent.SampleProject.props" />
|
||||
</Project>
|
|
@ -1,27 +0,0 @@
|
|||
---
|
||||
title: SettingsExpander
|
||||
author: niels9001
|
||||
description: An expander control that can be used to create Windows 11 style settings experiences.
|
||||
keywords: SettingsCard, SettingsExpander, Expander, Control, Layout, Settings
|
||||
dev_langs:
|
||||
- csharp
|
||||
category: Controls
|
||||
subcategory: Layout
|
||||
discussion-id: 129
|
||||
issue-id: 216
|
||||
icon: Assets/SettingsExpander.png
|
||||
---
|
||||
|
||||
The `SettingsExpander` can be used to group multiple `SettingsCard`s into a single collapsable group.
|
||||
|
||||
A `SettingsExpander` can have it's own content to display a setting on the right, just like a `SettingsCard`, but in addition can have any number of extra `Items` to include as additional settings. These items are `SettingsCard`s themselves, which means you can easily move a setting into or out of Expanders just by cutting and pasting their XAML!
|
||||
|
||||
> [!SAMPLE SettingsExpanderSample]
|
||||
|
||||
You can easily override certain properties to create custom experiences. For instance, you can customize the `ContentAlignment` of a `SettingsCard`, to align your content to the Right (default), Left (hiding the `HeaderIcon`, `Header` and `Description`) or Vertically (usually best paired with changing the `HorizontalContentAlignment` to `Stretch`).
|
||||
|
||||
`SettingsExpander` is also an `ItemsControl`, so its items can be driven by a collection and the `ItemsSource` property. You can use the `ItemTemplate` to define how your data object is represented as a `SettingsCard`, as shown below. The `ItemsHeader` and `ItemsFooter` property can be used to host custom content at the start or end of the items list.
|
||||
|
||||
> [!SAMPLE SettingsExpanderItemsSourceSample]
|
||||
|
||||
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.
|
|
@ -1,92 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<Page x:Class="SettingsControlsExperiment.Samples.SettingsExpanderItemsSourceSample"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:local="using:SettingsControlsExperiment.Samples"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.Labs.WinUI.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
<StackPanel Spacing="3">
|
||||
<labs:SettingsExpander Description="The SettingsExpander can use ItemsSource to define its Items."
|
||||
Header="Settings Expander with ItemsSource"
|
||||
ItemsSource="{x:Bind MyDataSet}">
|
||||
<labs:SettingsExpander.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsExpander.HeaderIcon>
|
||||
<labs:SettingsExpander.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:MyDataModel">
|
||||
<labs:SettingsCard Description="{x:Bind Info}"
|
||||
Header="{x:Bind Name}">
|
||||
<HyperlinkButton Content="{x:Bind LinkDescription}"
|
||||
NavigateUri="{x:Bind Url}" />
|
||||
</labs:SettingsCard>
|
||||
</DataTemplate>
|
||||
</labs:SettingsExpander.ItemTemplate>
|
||||
<labs:SettingsExpander.ItemsHeader>
|
||||
<muxc:InfoBar Title="This is the ItemsHeader"
|
||||
BorderThickness="0"
|
||||
CornerRadius="0"
|
||||
IsIconVisible="False"
|
||||
IsOpen="True"
|
||||
Severity="Success">
|
||||
<muxc:InfoBar.ActionButton>
|
||||
<HyperlinkButton Content="It can host custom content" />
|
||||
</muxc:InfoBar.ActionButton>
|
||||
</muxc:InfoBar>
|
||||
</labs:SettingsExpander.ItemsHeader>
|
||||
<labs:SettingsExpander.ItemsFooter>
|
||||
<labs:SettingsCard Header="This is the ItemsFooter"
|
||||
Style="{StaticResource DefaultSettingsExpanderItemStyle}">
|
||||
<Button Content="Add a device" />
|
||||
</labs:SettingsCard>
|
||||
</labs:SettingsExpander.ItemsFooter>
|
||||
</labs:SettingsExpander>
|
||||
|
||||
<labs:SettingsExpander Description="SettingsExpander can use a DataTemplate, DataTemplateSelector, or IElementFactory for its ItemTemplate."
|
||||
Header="Settings Expander with a custom ItemTemplate"
|
||||
ItemsSource="{x:Bind MyDataSet}">
|
||||
<labs:SettingsExpander.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsExpander.HeaderIcon>
|
||||
<labs:SettingsExpander.ItemTemplate>
|
||||
<local:MyDataModelTemplateSelector>
|
||||
<local:MyDataModelTemplateSelector.ButtonTemplate>
|
||||
<DataTemplate x:DataType="local:MyDataModel">
|
||||
<labs:SettingsCard Description="{x:Bind ItemType}"
|
||||
Header="{x:Bind Name}">
|
||||
<Button Click="Button_Click"
|
||||
Content="{x:Bind LinkDescription}" />
|
||||
</labs:SettingsCard>
|
||||
</DataTemplate>
|
||||
</local:MyDataModelTemplateSelector.ButtonTemplate>
|
||||
|
||||
<local:MyDataModelTemplateSelector.LinkButtonTemplate>
|
||||
<DataTemplate x:DataType="local:MyDataModel">
|
||||
<labs:SettingsCard Description="{x:Bind ItemType}"
|
||||
Header="{x:Bind Name}">
|
||||
<HyperlinkButton Content="{x:Bind LinkDescription}"
|
||||
NavigateUri="{x:Bind Url}" />
|
||||
</labs:SettingsCard>
|
||||
</DataTemplate>
|
||||
</local:MyDataModelTemplateSelector.LinkButtonTemplate>
|
||||
|
||||
<local:MyDataModelTemplateSelector.NoButtonTemplate>
|
||||
<DataTemplate x:DataType="local:MyDataModel">
|
||||
<labs:SettingsCard Description="{x:Bind ItemType}"
|
||||
Header="{x:Bind Name}" />
|
||||
</DataTemplate>
|
||||
</local:MyDataModelTemplateSelector.NoButtonTemplate>
|
||||
</local:MyDataModelTemplateSelector>
|
||||
</labs:SettingsExpander.ItemTemplate>
|
||||
</labs:SettingsExpander>
|
||||
</StackPanel>
|
||||
</Page>
|
|
@ -1,86 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Windows.System;
|
||||
|
||||
namespace SettingsControlsExperiment.Samples;
|
||||
|
||||
[ToolkitSample(id: nameof(SettingsExpanderItemsSourceSample), "SettingsExpanderItemsSource", description: "The SettingsExpander can also be filled with items based on a collection.")]
|
||||
public sealed partial class SettingsExpanderItemsSourceSample : Page
|
||||
{
|
||||
|
||||
public ObservableCollection<MyDataModel> MyDataSet = new() {
|
||||
new()
|
||||
{
|
||||
Name = "First Item",
|
||||
Info = "More about first item.",
|
||||
ItemType = "Item type: Button",
|
||||
LinkDescription = "Click here for more on first item.",
|
||||
Url = "https://microsoft.com/",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Second Item",
|
||||
Info = "More about second item.",
|
||||
ItemType = "Item type: Link button",
|
||||
LinkDescription = "Click here for more on second item.",
|
||||
Url = "https://xbox.com/",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Third Item",
|
||||
Info = "More about third item.",
|
||||
ItemType = "Item type: No button",
|
||||
LinkDescription = "Click here for more on third item.",
|
||||
Url = "https://toolkitlabs.dev/",
|
||||
},
|
||||
};
|
||||
|
||||
public SettingsExpanderItemsSourceSample()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private async void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_ = await Launcher.LaunchUriAsync(new("https://microsoft.com/"));
|
||||
}
|
||||
}
|
||||
|
||||
public class MyDataModel
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
|
||||
public string? Info { get; set; }
|
||||
|
||||
public string? ItemType { get; set; }
|
||||
|
||||
public string? LinkDescription { get; set; }
|
||||
|
||||
public string? Url { get; set; }
|
||||
}
|
||||
|
||||
public class MyDataModelTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate? ButtonTemplate { get; set; }
|
||||
public DataTemplate? LinkButtonTemplate { get; set; }
|
||||
public DataTemplate? NoButtonTemplate { get; set; }
|
||||
|
||||
protected override DataTemplate SelectTemplateCore(object item)
|
||||
{
|
||||
var itm = (MyDataModel)item;
|
||||
if (itm.ItemType?.EndsWith("Button") == true)
|
||||
{
|
||||
return ButtonTemplate!;
|
||||
}
|
||||
else if (itm.ItemType?.EndsWith("Link button") == true)
|
||||
{
|
||||
return LinkButtonTemplate!;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NoButtonTemplate!;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<Page x:Class="SettingsControlsExperiment.Samples.SettingsExpanderSample"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<labs:SettingsExpander x:Name="settingsCard"
|
||||
Description="The SettingsExpander has the same properties as a Card, and you can set SettingsCard as part of the Items collection."
|
||||
Header="SettingsExpander"
|
||||
IsEnabled="{x:Bind IsCardEnabled, Mode=OneWay}"
|
||||
IsExpanded="{x:Bind IsCardExpanded, Mode=OneWay}">
|
||||
<!-- TODO: This should be TwoWay bound but throws compile error in Uno. -->
|
||||
<labs:SettingsExpander.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsExpander.HeaderIcon>
|
||||
<ComboBox SelectedIndex="0">
|
||||
<ComboBoxItem>Option 1</ComboBoxItem>
|
||||
<ComboBoxItem>Option 2</ComboBoxItem>
|
||||
<ComboBoxItem>Option 3</ComboBoxItem>
|
||||
</ComboBox>
|
||||
|
||||
<labs:SettingsExpander.Items>
|
||||
<labs:SettingsCard Header="A basic SettingsCard within an SettingsExpander">
|
||||
<Button Content="Button" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard Description="SettingsCard within an Expander can be made clickable too!"
|
||||
Header="This item can be clicked"
|
||||
IsClickEnabled="True" />
|
||||
|
||||
<labs:SettingsCard ContentAlignment="Left">
|
||||
<CheckBox Content="Here the ContentAlignment is set to Left. This is great for e.g. CheckBoxes or RadioButtons." />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard HorizontalContentAlignment="Left"
|
||||
ContentAlignment="Vertical"
|
||||
Description="You can also align your content vertically. Make sure to set the HorizontalAlignment to Left when you do!"
|
||||
Header="Vertically aligned">
|
||||
<GridView SelectedIndex="1">
|
||||
<GridViewItem>
|
||||
<Border Width="64"
|
||||
Height="64"
|
||||
Background="#0078D4"
|
||||
CornerRadius="4" />
|
||||
</GridViewItem>
|
||||
<GridViewItem>
|
||||
<Border Width="64"
|
||||
Height="64"
|
||||
Background="#005EB7"
|
||||
CornerRadius="4" />
|
||||
</GridViewItem>
|
||||
<GridViewItem>
|
||||
<Border Width="64"
|
||||
Height="64"
|
||||
Background="#003D92"
|
||||
CornerRadius="4" />
|
||||
</GridViewItem>
|
||||
<GridViewItem>
|
||||
<Border Width="64"
|
||||
Height="64"
|
||||
Background="#001968"
|
||||
CornerRadius="4" />
|
||||
</GridViewItem>
|
||||
</GridView>
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard Description="You can override the Left indention of a SettingsCard by overriding the SettingsCardLeftIndention"
|
||||
Header="Customization">
|
||||
<labs:SettingsCard.Resources>
|
||||
<x:Double x:Key="SettingsCardLeftIndention">40</x:Double>
|
||||
</labs:SettingsCard.Resources>
|
||||
</labs:SettingsCard>
|
||||
</labs:SettingsExpander.Items>
|
||||
</labs:SettingsExpander>
|
||||
</Page>
|
|
@ -1,16 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace SettingsControlsExperiment.Samples;
|
||||
|
||||
[ToolkitSampleBoolOption("IsCardExpanded", false, Title = "Is Expanded")]
|
||||
[ToolkitSampleBoolOption("IsCardEnabled", true, Title = "Is Enabled")]
|
||||
[ToolkitSample(id: nameof(SettingsExpanderSample), "SettingsExpander", description: "The SettingsExpander can be used to group settings. SettingsCards can be customized in terms of alignment and content.")]
|
||||
public sealed partial class SettingsExpanderSample : Page
|
||||
{
|
||||
public SettingsExpanderSample()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Settings Page Example
|
||||
author: niels9001
|
||||
description: A full example of building a Windows 11 style settings experience with SettingsCard and SettingsExpander.
|
||||
keywords: SettingsCard, SettingsExpander, Example, Control, Layout, Settings
|
||||
dev_langs:
|
||||
- csharp
|
||||
category: Controls
|
||||
subcategory: Layout
|
||||
discussion-id: 129
|
||||
issue-id: 216
|
||||
icon: Assets/SettingsExpander.png
|
||||
---
|
||||
|
||||
> [!SAMPLE SettingsPageExample]
|
|
@ -1,119 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<Page x:Class="SettingsControlsExperiment.Samples.SettingsPageExample"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<!-- These styles can be referenced to create a consistent SettingsPage layout -->
|
||||
|
||||
<!-- Spacing between cards -->
|
||||
<x:Double x:Key="SettingsCardSpacing">3</x:Double>
|
||||
|
||||
<!-- Style (inc. the correct spacing) of a section header -->
|
||||
<Style x:Key="SettingsSectionHeaderTextBlockStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Style.Setters>
|
||||
<Setter Property="Margin" Value="1,29,0,5" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
<ScrollViewer>
|
||||
<Grid>
|
||||
<StackPanel MaxWidth="1000"
|
||||
HorizontalAlignment="Stretch"
|
||||
Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<win:StackPanel.ChildrenTransitions>
|
||||
<win:EntranceThemeTransition FromVerticalOffset="50" />
|
||||
<win:RepositionThemeTransition IsStaggeringEnabled="False" />
|
||||
</win:StackPanel.ChildrenTransitions>
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="Section 1" />
|
||||
<labs:SettingsCard Description="This is a default card, with the Header, HeaderIcon, Description and Content set"
|
||||
Header="This is the Header">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch IsOn="True" />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsExpander Description="The SettingsExpander has the same properties as a SettingsCard"
|
||||
Header="SettingsExpander">
|
||||
<labs:SettingsExpander.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsExpander.HeaderIcon>
|
||||
<Button Content="Content"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
|
||||
<labs:SettingsExpander.Items>
|
||||
<labs:SettingsCard Header="A basic SettingsCard within an SettingsExpander">
|
||||
<Button Content="Button" />
|
||||
</labs:SettingsCard>
|
||||
<labs:SettingsCard Description="SettingsCard within an Expander can be made clickable too!"
|
||||
Header="This item can be clicked"
|
||||
IsClickEnabled="True" />
|
||||
|
||||
<labs:SettingsCard ContentAlignment="Left">
|
||||
<CheckBox Content="Here the ContentAlignment is set to Left. This is great for e.g. CheckBoxes or RadioButtons" />
|
||||
</labs:SettingsCard>
|
||||
</labs:SettingsExpander.Items>
|
||||
</labs:SettingsExpander>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="Section 2" />
|
||||
<labs:SettingsCard Description="Another card to show grouping of cards"
|
||||
Header="Another SettingsCard">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<ComboBox SelectedIndex="0">
|
||||
<ComboBoxItem>Option 1</ComboBoxItem>
|
||||
<ComboBoxItem>Option 2</ComboBoxItem>
|
||||
<ComboBoxItem>Option 3</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</labs:SettingsCard>
|
||||
|
||||
<labs:SettingsCard Description="Another card to show grouping of cards"
|
||||
Header="Yet another SettingsCard">
|
||||
<labs:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</labs:SettingsCard.HeaderIcon>
|
||||
<Button Content="Content" />
|
||||
</labs:SettingsCard>
|
||||
|
||||
<!-- Example 'About' section -->
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="About" />
|
||||
|
||||
<labs:SettingsExpander Description="© 2023. All rights reserved."
|
||||
Header="Community Toolkit Gallery">
|
||||
<labs:SettingsExpander.HeaderIcon>
|
||||
<BitmapIcon ShowAsMonochrome="False"
|
||||
UriSource="ms-appx:///Assets/AppTitleBar.scale-200.png" />
|
||||
</labs:SettingsExpander.HeaderIcon>
|
||||
<TextBlock win:IsTextSelectionEnabled="True"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="Version 1.0.0.0" />
|
||||
<labs:SettingsExpander.Items>
|
||||
<labs:SettingsCard HorizontalContentAlignment="Left"
|
||||
ContentAlignment="Left">
|
||||
<StackPanel Margin="-12,0,0,0"
|
||||
Orientation="Vertical">
|
||||
<HyperlinkButton Content="Link 1" />
|
||||
<HyperlinkButton Content="Link 2" />
|
||||
<HyperlinkButton Content="Link 3" />
|
||||
</StackPanel>
|
||||
</labs:SettingsCard>
|
||||
</labs:SettingsExpander.Items>
|
||||
</labs:SettingsExpander>
|
||||
<HyperlinkButton Margin="0,8,0,0"
|
||||
Content="Send feedback" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Page>
|
|
@ -1,14 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace SettingsControlsExperiment.Samples;
|
||||
|
||||
[ToolkitSample(id: nameof(SettingsPageExample), "Settings Page Example", description: "A complete settings page example.")]
|
||||
public sealed partial class SettingsPageExample : Page
|
||||
{
|
||||
public SettingsPageExample()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// These `InternalsVisibleTo` calls are intended to make it easier for
|
||||
// for any internal code to be testable in all the different test projects
|
||||
// used with the Labs infrastructure.
|
||||
[assembly: InternalsVisibleTo("SettingsControls.Tests.Uwp")]
|
||||
[assembly: InternalsVisibleTo("SettingsControls.Tests.WinAppSdk")]
|
||||
[assembly: InternalsVisibleTo("CommunityToolkit.Tests.Uwp")]
|
||||
[assembly: InternalsVisibleTo("CommunityToolkit.Tests.WinAppSdk")]
|
|
@ -1,20 +0,0 @@
|
|||
<Project Sdk="MSBuild.Sdk.Extras/3.0.23">
|
||||
<PropertyGroup>
|
||||
<ToolkitComponentName>SettingsControls</ToolkitComponentName>
|
||||
<Description>This package contains the SettingsCard and SettingsExpander controls.</Description>
|
||||
<Version>0.0.18</Version>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
|
||||
<!-- Rns suffix is required for namespaces shared across projects. See https://github.com/CommunityToolkit/Labs-Windows/issues/152 -->
|
||||
<RootNamespace>CommunityToolkit.Labs.WinUI.SettingsControlsRns</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="SettingsExpander\SettingsExpander.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sets this up as a toolkit component's source project -->
|
||||
<Import Project="$(ToolingDirectory)\ToolkitComponent.SourceProject.props" />
|
||||
</Project>
|
|
@ -1,31 +0,0 @@
|
|||
<!--
|
||||
WinUI 2 under UWP uses TargetFramework uap10.0.*
|
||||
WinUI 3 under WinAppSdk uses TargetFramework net6.0-windows10.*
|
||||
However, under Uno-powered platforms, both WinUI 2 and 3 can share the same TargetFramework.
|
||||
|
||||
MSBuild doesn't play nicely with this out of the box, so we've made it easy for you.
|
||||
|
||||
For .NET Standard packages, you can use the Nuget Package Manager in Visual Studio.
|
||||
For UWP / WinAppSDK / Uno packages, place the package references here.
|
||||
-->
|
||||
<Project>
|
||||
<!-- WinUI 2 / UWP -->
|
||||
<ItemGroup Condition="'$(IsUwp)' == 'true'">
|
||||
<PackageReference Include="CommunityToolkit.Uwp.Triggers" Version="8.0.0-beta.1"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- WinUI 2 / Uno -->
|
||||
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '2'">
|
||||
<PackageReference Include="CommunityToolkit.Uwp.Triggers" Version="8.0.0-beta.1"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- WinUI 3 / WinAppSdk -->
|
||||
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.0.0-beta.1"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- WinUI 3 / Uno -->
|
||||
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '3'">
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.0.0-beta.1"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,9 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
internal static partial class ControlHelpers
|
||||
{
|
||||
internal static bool IsXamlRootAvailable { get; } = Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot");
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
// Adapted from https://github.com/rudyhuyn/XamlPlus
|
||||
internal static class ResourceDictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Copies the <see cref="ResourceDictionary"/> provided as a parameter into the calling dictionary, includes overwriting the source location, theme dictionaries, and merged dictionaries.
|
||||
/// </summary>
|
||||
/// <param name="destination">ResourceDictionary to copy values to.</param>
|
||||
/// <param name="source">ResourceDictionary to copy values from.</param>
|
||||
internal static void CopyFrom(this ResourceDictionary destination, ResourceDictionary source)
|
||||
{
|
||||
if (source.Source != null)
|
||||
{
|
||||
destination.Source = source.Source;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clone theme dictionaries
|
||||
if (source.ThemeDictionaries != null)
|
||||
{
|
||||
foreach (var theme in source.ThemeDictionaries)
|
||||
{
|
||||
if (theme.Value is ResourceDictionary themedResource)
|
||||
{
|
||||
var themeDictionary = new ResourceDictionary();
|
||||
themeDictionary.CopyFrom(themedResource);
|
||||
destination.ThemeDictionaries[theme.Key] = themeDictionary;
|
||||
}
|
||||
else
|
||||
{
|
||||
destination.ThemeDictionaries[theme.Key] = theme.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clone merged dictionaries
|
||||
if (source.MergedDictionaries != null)
|
||||
{
|
||||
foreach (var mergedResource in source.MergedDictionaries)
|
||||
{
|
||||
var themeDictionary = new ResourceDictionary();
|
||||
themeDictionary.CopyFrom(mergedResource);
|
||||
destination.MergedDictionaries.Add(themeDictionary);
|
||||
}
|
||||
}
|
||||
|
||||
// Clone all contents
|
||||
foreach (var item in source)
|
||||
{
|
||||
destination[item.Key] = item.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
// Adapted from https://github.com/rudyhuyn/XamlPlus
|
||||
public static partial class StyleExtensions
|
||||
{
|
||||
// Used to distinct normal ResourceDictionary and the one we add.
|
||||
private sealed class StyleExtensionResourceDictionary : ResourceDictionary
|
||||
{
|
||||
}
|
||||
|
||||
public static ResourceDictionary GetResources(Style obj)
|
||||
{
|
||||
return (ResourceDictionary)obj.GetValue(ResourcesProperty);
|
||||
}
|
||||
|
||||
public static void SetResources(Style obj, ResourceDictionary value)
|
||||
{
|
||||
obj.SetValue(ResourcesProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ResourcesProperty =
|
||||
DependencyProperty.RegisterAttached("Resources", typeof(ResourceDictionary), typeof(StyleExtensions), new PropertyMetadata(null, ResourcesChanged));
|
||||
|
||||
private static void ResourcesChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(sender is FrameworkElement frameworkElement))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var mergedDictionaries = frameworkElement.Resources?.MergedDictionaries;
|
||||
if (mergedDictionaries == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var existingResourceDictionary =
|
||||
mergedDictionaries.FirstOrDefault(c => c is StyleExtensionResourceDictionary);
|
||||
if (existingResourceDictionary != null)
|
||||
{
|
||||
// Remove the existing resource dictionary
|
||||
mergedDictionaries.Remove(existingResourceDictionary);
|
||||
}
|
||||
|
||||
if (e.NewValue is ResourceDictionary resource)
|
||||
{
|
||||
var clonedResources = new StyleExtensionResourceDictionary();
|
||||
clonedResources.CopyFrom(resource);
|
||||
mergedDictionaries.Add(clonedResources);
|
||||
}
|
||||
|
||||
if (frameworkElement.IsLoaded)
|
||||
{
|
||||
// Only force if the style was applied after the control was loaded
|
||||
ForceControlToReloadThemeResources(frameworkElement);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ForceControlToReloadThemeResources(FrameworkElement frameworkElement)
|
||||
{
|
||||
// To force the refresh of all resource references.
|
||||
// Note: Doesn't work when in high-contrast.
|
||||
var currentRequestedTheme = frameworkElement.RequestedTheme;
|
||||
frameworkElement.RequestedTheme = currentRequestedTheme == ElementTheme.Dark
|
||||
? ElementTheme.Light
|
||||
: ElementTheme.Dark;
|
||||
frameworkElement.RequestedTheme = currentRequestedTheme;
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
public partial class SettingsCard : ButtonBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Header"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||
nameof(Header),
|
||||
typeof(object),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: null, (d, e) => ((SettingsCard)d).OnHeaderPropertyChanged((object)e.OldValue, (object)e.NewValue)));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Description"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||
nameof(Description),
|
||||
typeof(object),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: null, (d, e) => ((SettingsCard)d).OnDescriptionPropertyChanged((object)e.OldValue, (object)e.NewValue)));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="HeaderIcon"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty HeaderIconProperty = DependencyProperty.Register(
|
||||
nameof(HeaderIcon),
|
||||
typeof(IconElement),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: null, (d, e) => ((SettingsCard)d).OnHeaderIconPropertyChanged((IconElement)e.OldValue, (IconElement)e.NewValue)));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="ActionIcon"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ActionIconProperty = DependencyProperty.Register(
|
||||
nameof(ActionIcon),
|
||||
typeof(IconElement),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: "\ue974"));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="ActionIconToolTip"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ActionIconToolTipProperty = DependencyProperty.Register(
|
||||
nameof(ActionIconToolTip),
|
||||
typeof(string),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: "More"));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="IsClickEnabled"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsClickEnabledProperty = DependencyProperty.Register(
|
||||
nameof(IsClickEnabled),
|
||||
typeof(bool),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: false, (d, e) => ((SettingsCard)d).OnIsClickEnabledPropertyChanged((bool)e.OldValue, (bool)e.NewValue)));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="ContentAlignment"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ContentAlignmentProperty = DependencyProperty.Register(
|
||||
nameof(ContentAlignment),
|
||||
typeof(ContentAlignment),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: ContentAlignment.Right));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="IsActionIconVisible"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsActionIconVisibleProperty = DependencyProperty.Register(
|
||||
nameof(IsActionIconVisible),
|
||||
typeof(bool),
|
||||
typeof(SettingsCard),
|
||||
new PropertyMetadata(defaultValue: true, (d, e) => ((SettingsCard)d).OnIsActionIconVisiblePropertyChanged((bool)e.OldValue, (bool)e.NewValue)));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Header.
|
||||
/// </summary>
|
||||
public object Header
|
||||
{
|
||||
get => (object)GetValue(HeaderProperty);
|
||||
set => SetValue(HeaderProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
#pragma warning disable CS0109 // Member does not hide an inherited member; new keyword is not required
|
||||
public new object Description
|
||||
#pragma warning restore CS0109 // Member does not hide an inherited member; new keyword is not required
|
||||
{
|
||||
get => (object)GetValue(DescriptionProperty);
|
||||
set => SetValue(DescriptionProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon on the left.
|
||||
/// </summary>
|
||||
public IconElement HeaderIcon
|
||||
{
|
||||
get => (IconElement)GetValue(HeaderIconProperty);
|
||||
set => SetValue(HeaderIconProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon that is shown when IsClickEnabled is set to true.
|
||||
/// </summary>
|
||||
public IconElement ActionIcon
|
||||
{
|
||||
get => (IconElement)GetValue(ActionIconProperty);
|
||||
set => SetValue(ActionIconProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tooltip of the ActionIcon.
|
||||
/// </summary>
|
||||
public string ActionIconToolTip
|
||||
{
|
||||
get => (string)GetValue(ActionIconToolTipProperty);
|
||||
set => SetValue(ActionIconToolTipProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the card can be clicked.
|
||||
/// </summary>
|
||||
public bool IsClickEnabled
|
||||
{
|
||||
get => (bool)GetValue(IsClickEnabledProperty);
|
||||
set => SetValue(IsClickEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alignment of the Content
|
||||
/// </summary>
|
||||
public ContentAlignment ContentAlignment
|
||||
{
|
||||
get => (ContentAlignment)GetValue(ContentAlignmentProperty);
|
||||
set => SetValue(ContentAlignmentProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the ActionIcon is shown.
|
||||
/// </summary>
|
||||
public bool IsActionIconVisible
|
||||
{
|
||||
get => (bool)GetValue(IsActionIconVisibleProperty);
|
||||
set => SetValue(IsActionIconVisibleProperty, value);
|
||||
}
|
||||
|
||||
protected virtual void OnIsClickEnabledPropertyChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
OnIsClickEnabledChanged();
|
||||
}
|
||||
protected virtual void OnHeaderIconPropertyChanged(IconElement oldValue, IconElement newValue)
|
||||
{
|
||||
OnHeaderIconChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnHeaderPropertyChanged(object oldValue, object newValue)
|
||||
{
|
||||
OnHeaderChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnDescriptionPropertyChanged(object oldValue, object newValue)
|
||||
{
|
||||
OnDescriptionChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnIsActionIconVisiblePropertyChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
OnActionIconChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public enum ContentAlignment
|
||||
{
|
||||
/// <summary>
|
||||
/// The Content is aligned to the right. Default state.
|
||||
/// </summary>
|
||||
Right,
|
||||
/// <summary>
|
||||
/// The Content is left-aligned while the Header, HeaderIcon and Description are collapsed. This is commonly used for Content types such as CheckBoxes, RadioButtons and custom layouts.
|
||||
/// </summary>
|
||||
Left,
|
||||
/// <summary>
|
||||
/// The Content is vertically aligned.
|
||||
/// </summary>
|
||||
Vertical
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
/// <summary>
|
||||
/// This is the base control to create consistent settings experiences, inline with the Windows 11 design language.
|
||||
/// A SettingsCard can also be hosted within a SettingsExpander.
|
||||
/// </summary>
|
||||
|
||||
[TemplatePart(Name = ActionIconPresenterHolder, Type = typeof(Viewbox))]
|
||||
[TemplatePart(Name = HeaderPresenter, Type = typeof(ContentPresenter))]
|
||||
[TemplatePart(Name = DescriptionPresenter, Type = typeof(ContentPresenter))]
|
||||
[TemplatePart(Name = HeaderIconPresenterHolder, Type = typeof(Viewbox))]
|
||||
public partial class SettingsCard : ButtonBase
|
||||
{
|
||||
internal const string NormalState = "Normal";
|
||||
internal const string PointerOverState = "PointerOver";
|
||||
internal const string PressedState = "Pressed";
|
||||
internal const string DisabledState = "Disabled";
|
||||
|
||||
internal const string ActionIconPresenterHolder = "PART_ActionIconPresenterHolder";
|
||||
internal const string HeaderPresenter = "PART_HeaderPresenter";
|
||||
internal const string DescriptionPresenter = "PART_DescriptionPresenter";
|
||||
internal const string HeaderIconPresenterHolder = "PART_HeaderIconPresenterHolder";
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SettingsCard"/> class.
|
||||
/// </summary>
|
||||
public SettingsCard()
|
||||
{
|
||||
this.DefaultStyleKey = typeof(SettingsCard);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
IsEnabledChanged -= OnIsEnabledChanged;
|
||||
OnActionIconChanged();
|
||||
OnHeaderChanged();
|
||||
OnHeaderIconChanged();
|
||||
OnDescriptionChanged();
|
||||
OnIsClickEnabledChanged();
|
||||
VisualStateManager.GoToState(this, IsEnabled ? NormalState : DisabledState, true);
|
||||
RegisterAutomation();
|
||||
IsEnabledChanged += OnIsEnabledChanged;
|
||||
}
|
||||
|
||||
private void RegisterAutomation()
|
||||
{
|
||||
if (Header is string headerString && headerString != string.Empty)
|
||||
{
|
||||
AutomationProperties.SetName(this, headerString);
|
||||
// We don't want to override an AutomationProperties.Name that is manually set, or if the Content basetype is of type ButtonBase (the ButtonBase.Content will be used then)
|
||||
if (Content is UIElement element && string.IsNullOrEmpty(AutomationProperties.GetName(element)) && element.GetType().BaseType != typeof(ButtonBase) && element.GetType() != typeof(TextBlock))
|
||||
{
|
||||
AutomationProperties.SetName(element, headerString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnableButtonInteraction()
|
||||
{
|
||||
DisableButtonInteraction();
|
||||
|
||||
IsTabStop = true;
|
||||
PointerEntered += Control_PointerEntered;
|
||||
PointerExited += Control_PointerExited;
|
||||
PointerCaptureLost += Control_PointerCaptureLost;
|
||||
PointerCanceled += Control_PointerCanceled;
|
||||
PreviewKeyDown += Control_PreviewKeyDown;
|
||||
PreviewKeyUp += Control_PreviewKeyUp;
|
||||
}
|
||||
|
||||
private void DisableButtonInteraction()
|
||||
{
|
||||
IsTabStop = false;
|
||||
PointerEntered -= Control_PointerEntered;
|
||||
PointerExited -= Control_PointerExited;
|
||||
PointerCaptureLost -= Control_PointerCaptureLost;
|
||||
PointerCanceled -= Control_PointerCanceled;
|
||||
PreviewKeyDown -= Control_PreviewKeyDown;
|
||||
PreviewKeyUp -= Control_PreviewKeyUp;
|
||||
}
|
||||
|
||||
private void Control_PreviewKeyUp(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if (e.Key == Windows.System.VirtualKey.Enter || e.Key == Windows.System.VirtualKey.Space || e.Key == Windows.System.VirtualKey.GamepadA)
|
||||
{
|
||||
VisualStateManager.GoToState(this, NormalState, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void Control_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if (e.Key == Windows.System.VirtualKey.Enter || e.Key == Windows.System.VirtualKey.Space || e.Key == Windows.System.VirtualKey.GamepadA)
|
||||
{
|
||||
// Check if the active focus is on the card itself - only then we show the pressed state.
|
||||
if (GetFocusedElement() is SettingsCard)
|
||||
{
|
||||
VisualStateManager.GoToState(this, PressedState, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Control_PointerEntered(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
base.OnPointerEntered(e);
|
||||
VisualStateManager.GoToState(this, PointerOverState, true);
|
||||
}
|
||||
|
||||
public void Control_PointerExited(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
base.OnPointerExited(e);
|
||||
VisualStateManager.GoToState(this, NormalState, true);
|
||||
}
|
||||
|
||||
private void Control_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
base.OnPointerCaptureLost(e);
|
||||
VisualStateManager.GoToState(this, NormalState, true);
|
||||
}
|
||||
|
||||
private void Control_PointerCanceled(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
base.OnPointerCanceled(e);
|
||||
VisualStateManager.GoToState(this, NormalState, true);
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerRoutedEventArgs e)
|
||||
{
|
||||
// e.Handled = true;
|
||||
if (IsClickEnabled)
|
||||
{
|
||||
base.OnPointerPressed(e);
|
||||
VisualStateManager.GoToState(this, PressedState, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPointerReleased(PointerRoutedEventArgs e)
|
||||
{
|
||||
if (IsClickEnabled)
|
||||
{
|
||||
base.OnPointerReleased(e);
|
||||
VisualStateManager.GoToState(this, NormalState, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates AutomationPeer
|
||||
/// </summary>
|
||||
/// <returns>An automation peer for <see cref="SettingsCard"/>.</returns>
|
||||
protected override AutomationPeer OnCreateAutomationPeer()
|
||||
{
|
||||
return new SettingsCardAutomationPeer(this);
|
||||
}
|
||||
|
||||
private void OnIsClickEnabledChanged()
|
||||
{
|
||||
OnActionIconChanged();
|
||||
if (IsClickEnabled)
|
||||
{
|
||||
EnableButtonInteraction();
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableButtonInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
VisualStateManager.GoToState(this, IsEnabled ? NormalState : DisabledState, true);
|
||||
}
|
||||
|
||||
private void OnActionIconChanged()
|
||||
{
|
||||
if (GetTemplateChild(ActionIconPresenterHolder) is FrameworkElement actionIconPresenter)
|
||||
{
|
||||
if (IsClickEnabled && IsActionIconVisible)
|
||||
{
|
||||
actionIconPresenter.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
actionIconPresenter.Visibility =Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHeaderIconChanged()
|
||||
{
|
||||
if (GetTemplateChild(HeaderIconPresenterHolder) is FrameworkElement headerIconPresenter)
|
||||
{
|
||||
headerIconPresenter.Visibility = HeaderIcon != null
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDescriptionChanged()
|
||||
{
|
||||
if (GetTemplateChild(DescriptionPresenter) is FrameworkElement descriptionPresenter)
|
||||
{
|
||||
descriptionPresenter.Visibility = Description != null
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHeaderChanged()
|
||||
{
|
||||
if (GetTemplateChild(HeaderPresenter) is FrameworkElement headerPresenter)
|
||||
{
|
||||
headerPresenter.Visibility = Header != null
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private FrameworkElement? GetFocusedElement()
|
||||
{
|
||||
if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null)
|
||||
{
|
||||
return FocusManager.GetFocusedElement(XamlRoot) as FrameworkElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FocusManager.GetFocusedElement() as FrameworkElement;
|
||||
}
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,47 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
/// <summary>
|
||||
/// AutomationPeer for SettingsCard
|
||||
/// </summary>
|
||||
public class SettingsCardAutomationPeer : FrameworkElementAutomationPeer
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SettingsCard"/> class.
|
||||
/// </summary>
|
||||
/// <param name="owner">SettingsCard</param>
|
||||
public SettingsCardAutomationPeer(SettingsCard owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the control type for the element that is associated with the UI Automation peer.
|
||||
/// </summary>
|
||||
/// <returns>The control type.</returns>
|
||||
protected override AutomationControlType GetAutomationControlTypeCore()
|
||||
{
|
||||
return AutomationControlType.Group;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType,
|
||||
/// differentiates the control represented by this AutomationPeer.
|
||||
/// </summary>
|
||||
/// <returns>The string that contains the name.</returns>
|
||||
protected override string GetClassNameCore()
|
||||
{
|
||||
string classNameCore = Owner.GetType().Name;
|
||||
#if DEBUG_AUTOMATION
|
||||
System.Diagnostics.Debug.WriteLine("SettingsCardAutomationPeer.GetClassNameCore returns " + classNameCore);
|
||||
#endif
|
||||
return classNameCore;
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
public partial class SettingsExpander
|
||||
{
|
||||
/// <summary>
|
||||
/// Fires when the SettingsExpander is opened
|
||||
/// </summary>
|
||||
public event EventHandler? Expanded;
|
||||
|
||||
/// <summary>
|
||||
/// Fires when the expander is closed
|
||||
/// </summary>
|
||||
public event EventHandler? Collapsed;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
//// Implement properties for ItemsControl like behavior.
|
||||
public partial class SettingsExpander
|
||||
{
|
||||
public IList<object> Items
|
||||
{
|
||||
get { return (IList<object>)GetValue(ItemsProperty); }
|
||||
set { SetValue(ItemsProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ItemsProperty =
|
||||
DependencyProperty.Register(nameof(Items), typeof(IList<object>), typeof(SettingsExpander), new PropertyMetadata(null, OnItemsConnectedPropertyChanged));
|
||||
|
||||
public object ItemsSource
|
||||
{
|
||||
get { return (object)GetValue(ItemsSourceProperty); }
|
||||
set { SetValue(ItemsSourceProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ItemsSourceProperty =
|
||||
DependencyProperty.Register(nameof(ItemsSource), typeof(object), typeof(SettingsExpander), new PropertyMetadata(null, OnItemsConnectedPropertyChanged));
|
||||
|
||||
public object ItemTemplate
|
||||
{
|
||||
get { return (object)GetValue(ItemTemplateProperty); }
|
||||
set { SetValue(ItemTemplateProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ItemTemplateProperty =
|
||||
DependencyProperty.Register(nameof(ItemTemplate), typeof(object), typeof(SettingsExpander), new PropertyMetadata(null));
|
||||
|
||||
public StyleSelector ItemContainerStyleSelector
|
||||
{
|
||||
get { return (StyleSelector)GetValue(ItemContainerStyleSelectorProperty); }
|
||||
set { SetValue(ItemContainerStyleSelectorProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ItemContainerStyleSelectorProperty =
|
||||
DependencyProperty.Register(nameof(ItemContainerStyleSelector), typeof(StyleSelector), typeof(SettingsExpander), new PropertyMetadata(null));
|
||||
|
||||
private static void OnItemsConnectedPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
if (dependencyObject is SettingsExpander expander && expander._itemsRepeater is not null)
|
||||
{
|
||||
var datasource = expander.ItemsSource;
|
||||
|
||||
if (datasource is null)
|
||||
{
|
||||
datasource = expander.Items;
|
||||
}
|
||||
|
||||
expander._itemsRepeater.ItemsSource = datasource;
|
||||
}
|
||||
}
|
||||
|
||||
private void ItemsRepeater_ElementPrepared(MUXC.ItemsRepeater sender, MUXC.ItemsRepeaterElementPreparedEventArgs args)
|
||||
{
|
||||
if (ItemContainerStyleSelector != null &&
|
||||
args.Element is FrameworkElement element &&
|
||||
element.ReadLocalValue(FrameworkElement.StyleProperty) == DependencyProperty.UnsetValue)
|
||||
{
|
||||
// TODO: Get item from args.Index?
|
||||
element.Style = ItemContainerStyleSelector.SelectStyle(null, element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
[ContentProperty(Name = nameof(Content))]
|
||||
public partial class SettingsExpander
|
||||
{
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Header"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||
nameof(Header),
|
||||
typeof(object),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: null));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Description"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||
nameof(Description),
|
||||
typeof(object),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: null));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="HeaderIcon"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty HeaderIconProperty = DependencyProperty.Register(
|
||||
nameof(HeaderIcon),
|
||||
typeof(IconElement),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: null));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Content"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
|
||||
nameof(Content),
|
||||
typeof(object),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: null));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Content"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ItemsHeaderProperty = DependencyProperty.Register(
|
||||
nameof(ItemsHeader),
|
||||
typeof(UIElement),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: null));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="Content"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ItemsFooterProperty = DependencyProperty.Register(
|
||||
nameof(ItemsFooter),
|
||||
typeof(UIElement),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: null));
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="DependencyProperty"/> for the <see cref="IsExpanded"/> property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register(
|
||||
nameof(IsExpanded),
|
||||
typeof(bool),
|
||||
typeof(SettingsExpander),
|
||||
new PropertyMetadata(defaultValue: false, (d, e) => ((SettingsExpander)d).OnIsExpandedPropertyChanged((bool)e.OldValue, (bool)e.NewValue)));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// <summary>
|
||||
/// Gets or sets the Header.
|
||||
/// </summary>
|
||||
public object Header
|
||||
{
|
||||
get => (object)GetValue(HeaderProperty);
|
||||
set => SetValue(HeaderProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Description.
|
||||
/// </summary>
|
||||
#pragma warning disable CS0109 // Member does not hide an inherited member; new keyword is not required
|
||||
public new object Description
|
||||
#pragma warning restore CS0109 // Member does not hide an inherited member; new keyword is not required
|
||||
{
|
||||
get => (object)GetValue(DescriptionProperty);
|
||||
set => SetValue(DescriptionProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HeaderIcon.
|
||||
/// </summary>
|
||||
public IconElement HeaderIcon
|
||||
{
|
||||
get => (IconElement)GetValue(HeaderIconProperty);
|
||||
set => SetValue(HeaderIconProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Content.
|
||||
/// </summary>
|
||||
public object Content
|
||||
{
|
||||
get => (object)GetValue(ContentProperty);
|
||||
set => SetValue(ContentProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ItemsFooter.
|
||||
/// </summary>
|
||||
public UIElement ItemsHeader
|
||||
{
|
||||
get => (UIElement)GetValue(ItemsHeaderProperty);
|
||||
set => SetValue(ItemsHeaderProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ItemsFooter.
|
||||
/// </summary>
|
||||
public UIElement ItemsFooter
|
||||
{
|
||||
get => (UIElement)GetValue(ItemsFooterProperty);
|
||||
set => SetValue(ItemsFooterProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IsExpanded state.
|
||||
/// </summary>
|
||||
public bool IsExpanded
|
||||
{
|
||||
get => (bool)GetValue(IsExpandedProperty);
|
||||
set => SetValue(IsExpandedProperty, value);
|
||||
}
|
||||
protected virtual void OnIsExpandedPropertyChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
OnIsExpandedChanged(oldValue, newValue);
|
||||
|
||||
if (newValue)
|
||||
{
|
||||
Expanded?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
Collapsed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
//// Note: ItemsRepeater will request all the available horizontal space: https://github.com/microsoft/microsoft-ui-xaml/issues/3842
|
||||
[TemplatePart(Name = PART_ItemsRepeater, Type = typeof(MUXC.ItemsRepeater))]
|
||||
public partial class SettingsExpander : Control
|
||||
{
|
||||
private const string PART_ItemsRepeater = "PART_ItemsRepeater";
|
||||
|
||||
private MUXC.ItemsRepeater? _itemsRepeater;
|
||||
|
||||
/// <summary>
|
||||
/// The SettingsExpander is a collapsable control to host multiple SettingsCards.
|
||||
/// </summary>
|
||||
public SettingsExpander()
|
||||
{
|
||||
this.DefaultStyleKey = typeof(SettingsExpander);
|
||||
Items = new List<object>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
RegisterAutomation();
|
||||
|
||||
if (_itemsRepeater != null)
|
||||
{
|
||||
_itemsRepeater.ElementPrepared -= this.ItemsRepeater_ElementPrepared;
|
||||
}
|
||||
|
||||
_itemsRepeater = GetTemplateChild(PART_ItemsRepeater) as MUXC.ItemsRepeater;
|
||||
|
||||
if (_itemsRepeater != null)
|
||||
{
|
||||
_itemsRepeater.ElementPrepared += this.ItemsRepeater_ElementPrepared;
|
||||
|
||||
// Update it's source based on our current items properties.
|
||||
OnItemsConnectedPropertyChanged(this, null!); // Can't get it to accept type here? (DependencyPropertyChangedEventArgs)EventArgs.Empty
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterAutomation()
|
||||
{
|
||||
if (Header is string headerString && headerString != string.Empty)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(headerString) && string.IsNullOrEmpty(AutomationProperties.GetName(this)))
|
||||
{
|
||||
AutomationProperties.SetName(this, headerString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates AutomationPeer
|
||||
/// </summary>
|
||||
/// <returns>An automation peer for <see cref="SettingsExpander"/>.</returns>
|
||||
protected override AutomationPeer OnCreateAutomationPeer()
|
||||
{
|
||||
return new SettingsExpanderAutomationPeer(this);
|
||||
}
|
||||
|
||||
private void OnIsExpandedChanged(bool oldValue, bool newValue)
|
||||
{
|
||||
var peer = FrameworkElementAutomationPeer.FromElement(this) as SettingsExpanderAutomationPeer;
|
||||
peer?.RaiseExpandedChangedEvent(newValue);
|
||||
}
|
||||
}
|
|
@ -1,578 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.Labs.WinUI.SettingsControls/SettingsCard/SettingsCard.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<x:String x:Key="SettingsExpanderChevronToolTip">Show all settings</x:String>
|
||||
<Thickness x:Key="SettingsExpanderHeaderPadding">16,16,4,16</Thickness>
|
||||
<Thickness x:Key="SettingsExpanderItemPadding">58,8,44,8</Thickness>
|
||||
<Thickness x:Key="SettingsExpanderItemBorderThickness">0,1,0,0</Thickness>
|
||||
<Thickness x:Key="ClickableSettingsExpanderItemPadding">58,8,16,8</Thickness>
|
||||
<x:Double x:Key="SettingsExpanderContentMinHeight">16</x:Double>
|
||||
<x:Double x:Key="SettingsExpanderChevronButtonWidth">32</x:Double>
|
||||
<x:Double x:Key="SettingsExpanderChevronButtonHeight">32</x:Double>
|
||||
|
||||
<Style x:Key="DefaultSettingsExpanderItemStyle"
|
||||
BasedOn="{StaticResource DefaultSettingsCardStyle}"
|
||||
TargetType="labs:SettingsCard">
|
||||
<Style.Setters>
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource SettingsExpanderItemBorderThickness}" />
|
||||
<Setter Property="MinHeight" Value="52" />
|
||||
<Setter Property="Padding" Value="{ThemeResource SettingsExpanderItemPadding}" />
|
||||
<Setter Property="CornerRadius" Value="0" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ClickableSettingsExpanderItemStyle"
|
||||
BasedOn="{StaticResource DefaultSettingsExpanderItemStyle}"
|
||||
TargetType="labs:SettingsCard">
|
||||
<Style.Setters>
|
||||
<Setter Property="Padding" Value="{ThemeResource ClickableSettingsExpanderItemPadding}" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
|
||||
<labs:SettingsExpanderItemStyleSelector x:Key="SettingsExpanderItemStyleSelector"
|
||||
ClickableStyle="{StaticResource ClickableSettingsExpanderItemStyle}"
|
||||
DefaultStyle="{StaticResource DefaultSettingsExpanderItemStyle}" />
|
||||
|
||||
<!-- Implicitly applied default style -->
|
||||
<Style BasedOn="{StaticResource DefaultSettingsExpanderStyle}"
|
||||
TargetType="labs:SettingsExpander" />
|
||||
|
||||
<Style x:Key="DefaultSettingsExpanderStyle"
|
||||
TargetType="labs:SettingsExpander">
|
||||
<Style.Setters>
|
||||
<Setter Property="Background" Value="{ThemeResource SettingsCardBackground}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SettingsCardForeground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SettingsCardBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource SettingsCardBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="MinHeight" Value="{ThemeResource SettingsCardMinHeight}" />
|
||||
<Setter Property="MinWidth" Value="{ThemeResource SettingsCardMinWidth}" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Padding" Value="{ThemeResource SettingsExpanderHeaderPadding}" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="ItemContainerStyleSelector" Value="{StaticResource SettingsExpanderItemStyleSelector}" />
|
||||
<Setter Property="FocusVisualMargin" Value="-3" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="labs:SettingsExpander">
|
||||
<muxc:Expander MinWidth="{TemplateBinding MinWidth}"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
win:AutomationProperties.HelpText="{TemplateBinding AutomationProperties.HelpText}"
|
||||
win:AutomationProperties.Name="{TemplateBinding AutomationProperties.Name}"
|
||||
IsExpanded="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{StaticResource SettingsExpanderExpanderStyle}">
|
||||
<muxc:Expander.Header>
|
||||
<labs:SettingsCard Padding="{StaticResource SettingsExpanderHeaderPadding}"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Content="{TemplateBinding Content}"
|
||||
Description="{TemplateBinding Description}"
|
||||
Header="{TemplateBinding Header}"
|
||||
HeaderIcon="{TemplateBinding HeaderIcon}"
|
||||
IsClickEnabled="False" />
|
||||
</muxc:Expander.Header>
|
||||
<muxc:Expander.Content>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentPresenter Content="{TemplateBinding ItemsHeader}" />
|
||||
<muxc:ItemsRepeater x:Name="PART_ItemsRepeater"
|
||||
Grid.Row="1"
|
||||
ItemTemplate="{Binding ItemTemplate, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
TabFocusNavigation="Local">
|
||||
<muxc:ItemsRepeater.Layout>
|
||||
<muxc:StackLayout Orientation="Vertical" />
|
||||
</muxc:ItemsRepeater.Layout>
|
||||
</muxc:ItemsRepeater>
|
||||
<ContentPresenter Grid.Row="2"
|
||||
Content="{TemplateBinding ItemsFooter}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Content>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsExpanderExpanderStyle"
|
||||
TargetType="muxc:Expander">
|
||||
<Setter Property="Background" Value="{ThemeResource ExpanderContentBackground}" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource ExpanderMinHeight}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderContentDownBorderThickness}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderContentBorderBrush}" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="muxc:Expander">
|
||||
<Grid MinWidth="{TemplateBinding MinWidth}"
|
||||
MaxWidth="{TemplateBinding MaxWidth}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition x:Name="Row0"
|
||||
Height="Auto" />
|
||||
<RowDefinition x:Name="Row1"
|
||||
Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="ExpandStates">
|
||||
<VisualState x:Name="ExpandUp">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpanderHeader.CornerRadius" Value="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BottomCornerRadiusFilterConverter}}" />
|
||||
</VisualState.Setters>
|
||||
<VisualState.Storyboard>
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="Visible" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0"
|
||||
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ContentHeight}" />
|
||||
<SplineDoubleKeyFrame KeySpline="0.0, 0.0, 0.0, 1.0"
|
||||
KeyTime="0:0:0.333"
|
||||
Value="0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState.Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="CollapseDown">
|
||||
<VisualState.Storyboard>
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0:0:0.2"
|
||||
Value="Collapsed" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0"
|
||||
Value="0" />
|
||||
<SplineDoubleKeyFrame KeySpline="1.0, 1.0, 0.0, 1.0"
|
||||
KeyTime="0:0:0.167"
|
||||
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.ContentHeight}" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState.Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="ExpandDown">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpanderHeader.CornerRadius" Value="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource TopCornerRadiusFilterConverter}}" />
|
||||
</VisualState.Setters>
|
||||
<VisualState.Storyboard>
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="Visible" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0"
|
||||
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeContentHeight}" />
|
||||
<SplineDoubleKeyFrame KeySpline="0.0, 0.0, 0.0, 1.0"
|
||||
KeyTime="0:0:0.333"
|
||||
Value="0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState.Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="CollapseUp">
|
||||
<VisualState.Storyboard>
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0:0:0.167"
|
||||
Value="Collapsed" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ExpanderContent"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0"
|
||||
Value="0" />
|
||||
<SplineDoubleKeyFrame KeySpline="1.0, 1.0, 0.0, 1.0"
|
||||
KeyTime="0:0:0.167"
|
||||
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeContentHeight}" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState.Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="ExpandDirectionStates">
|
||||
<VisualState x:Name="Down" />
|
||||
<VisualState x:Name="Up">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpanderHeader.Style" Value="{StaticResource ExpanderHeaderUpStyle}" />
|
||||
<Setter Target="ExpanderContent.BorderThickness" Value="{StaticResource ExpanderContentUpBorderThickness}" />
|
||||
<Setter Target="ExpanderContent.CornerRadius" Value="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource TopCornerRadiusFilterConverter}}" />
|
||||
<Setter Target="ExpanderHeader.(Grid.Row)" Value="1" />
|
||||
<Setter Target="ExpanderContentClip.(Grid.Row)" Value="0" />
|
||||
<Setter Target="Row0.Height" Value="*" />
|
||||
<Setter Target="Row1.Height" Value="Auto" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<ToggleButton x:Name="ExpanderHeader"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
Padding="{StaticResource ExpanderHeaderPadding}"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="{StaticResource ExpanderHeaderHorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{StaticResource ExpanderHeaderVerticalContentAlignment}"
|
||||
win:AutomationProperties.AutomationId="ExpanderToggleButton"
|
||||
win:AutomationProperties.Name="{TemplateBinding AutomationProperties.Name}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{ThemeResource ExpanderHeaderBorderBrush}"
|
||||
BorderThickness="{ThemeResource ExpanderHeaderBorderThickness}"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
IsEnabled="{TemplateBinding IsEnabled}"
|
||||
IsTabStop="True"
|
||||
Style="{StaticResource SettingsExpanderHeaderDownStyle}" />
|
||||
<!-- The clip is a composition clip applied in code -->
|
||||
<Border x:Name="ExpanderContentClip"
|
||||
Grid.Row="1">
|
||||
<Border x:Name="ExpanderContent"
|
||||
MinHeight="{ThemeResource SettingsExpanderContentMinHeight}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{StaticResource ExpanderContentDownBorderThickness}"
|
||||
CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BottomCornerRadiusFilterConverter}}"
|
||||
Visibility="Collapsed">
|
||||
<ContentPresenter Margin="0,-2,0,0"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" />
|
||||
<Border.RenderTransform>
|
||||
<CompositeTransform />
|
||||
</Border.RenderTransform>
|
||||
</Border>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsExpanderHeaderDownStyle"
|
||||
TargetType="ToggleButton">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Grid x:Name="ToggleButtonGrid"
|
||||
Width="{TemplateBinding Width}"
|
||||
MinWidth="{TemplateBinding MinWidth}"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
MaxWidth="{TemplateBinding MaxWidth}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{ThemeResource ExpanderHeaderBorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronPointerOverForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpandCollapseChevron.(muxc:AnimatedIcon.State)" Value="PointerOverOff" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronPressedForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpandCollapseChevron.(muxc:AnimatedIcon.State)" Value="PressedOff" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderDisabledForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderDisabledForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Checked">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevronBorder"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronBorderBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevronBorder"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronBackground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpandCollapseChevron.(muxc:AnimatedIcon.State)" Value="NormalOn" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="CheckedPointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronPointerOverForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpandCollapseChevron.(muxc:AnimatedIcon.State)" Value="PointerOverOn" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="CheckedPressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderChevronPressedForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpandCollapseChevron.(muxc:AnimatedIcon.State)" Value="PressedOn" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="CheckedDisabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderDisabledForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ExpandCollapseChevron"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ExpanderHeaderDisabledForeground}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ToggleButtonGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ExpandCollapseChevron.(muxc:AnimatedIcon.State)" Value="NormalOn" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Indeterminate" />
|
||||
<VisualState x:Name="IndeterminatePointerOver" />
|
||||
<VisualState x:Name="IndeterminatePressed" />
|
||||
<VisualState x:Name="IndeterminateDisabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
win:AutomationProperties.AccessibilityView="Raw"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}"
|
||||
Foreground="{TemplateBinding Foreground}" />
|
||||
|
||||
<ContentControl x:Name="ExpandCollapseChevronBorder"
|
||||
Grid.Column="1"
|
||||
Width="{StaticResource SettingsExpanderChevronButtonWidth}"
|
||||
Height="{StaticResource SettingsExpanderChevronButtonHeight}"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Background="{ThemeResource ExpanderChevronBackground}"
|
||||
BorderBrush="{ThemeResource ExpanderChevronBorderBrush}"
|
||||
BorderThickness="{ThemeResource ExpanderChevronBorderThickness}"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}"
|
||||
FocusVisualMargin="-3"
|
||||
IsTabStop="False"
|
||||
ToolTipService.ToolTip="{StaticResource SettingsExpanderChevronToolTip}"
|
||||
UseSystemFocusVisuals="True">
|
||||
<muxc:AnimatedIcon x:Name="ExpandCollapseChevron"
|
||||
Width="16"
|
||||
Height="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
muxc:AnimatedIcon.State="NormalOff"
|
||||
win:AutomationProperties.AccessibilityView="Raw"
|
||||
Foreground="{ThemeResource ExpanderChevronForeground}"
|
||||
RenderTransformOrigin="0.5, 0.5">
|
||||
<animatedvisuals:AnimatedChevronUpDownSmallVisualSource />
|
||||
<muxc:AnimatedIcon.FallbackIconSource>
|
||||
<muxc:FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
Glyph="{StaticResource ExpanderChevronDownGlyph}"
|
||||
IsTextScaleFactorEnabled="False" />
|
||||
</muxc:AnimatedIcon.FallbackIconSource>
|
||||
</muxc:AnimatedIcon>
|
||||
</ContentControl>
|
||||
</Grid>
|
||||
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
|
@ -1,67 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
/// <summary>
|
||||
/// AutomationPeer for SettingsExpander
|
||||
/// </summary>
|
||||
public class SettingsExpanderAutomationPeer : FrameworkElementAutomationPeer
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SettingsExpander"/> class.
|
||||
/// </summary>
|
||||
/// <param name="owner">SettingsExpander</param>
|
||||
public SettingsExpanderAutomationPeer(SettingsExpander owner)
|
||||
: base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the control type for the element that is associated with the UI Automation peer.
|
||||
/// </summary>
|
||||
/// <returns>The control type.</returns>
|
||||
protected override AutomationControlType GetAutomationControlTypeCore()
|
||||
{
|
||||
return AutomationControlType.Group;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by GetClassName that gets a human readable name that, in addition to AutomationControlType,
|
||||
/// differentiates the control represented by this AutomationPeer.
|
||||
/// </summary>
|
||||
/// <returns>The string that contains the name.</returns>
|
||||
protected override string GetClassNameCore()
|
||||
{
|
||||
string classNameCore = Owner.GetType().Name;
|
||||
#if DEBUG_AUTOMATION
|
||||
System.Diagnostics.Debug.WriteLine("SettingsCardAutomationPeer.GetClassNameCore returns " + classNameCore);
|
||||
#endif
|
||||
return classNameCore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the property changed event for this AutomationPeer for the provided identifier.
|
||||
/// Narrator does not announce this due to: https://github.com/microsoft/microsoft-ui-xaml/issues/3469
|
||||
/// </summary>
|
||||
/// <param name="newValue">New Expanded state</param>
|
||||
public void RaiseExpandedChangedEvent(bool newValue)
|
||||
{
|
||||
ExpandCollapseState newState = (newValue == true) ?
|
||||
ExpandCollapseState.Expanded :
|
||||
ExpandCollapseState.Collapsed;
|
||||
|
||||
ExpandCollapseState oldState = (newState == ExpandCollapseState.Expanded) ?
|
||||
ExpandCollapseState.Collapsed :
|
||||
ExpandCollapseState.Expanded;
|
||||
|
||||
#if !HAS_UNO
|
||||
RaisePropertyChangedEvent(ExpandCollapsePatternIdentifiers.ExpandCollapseStateProperty, oldState, newState);
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace CommunityToolkit.Labs.WinUI;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="StyleSelector"/> used by <see cref="SettingsExpander"/> to choose the proper <see cref="SettingsCard"/> container style (clickable or not).
|
||||
/// </summary>
|
||||
public class SettingsExpanderItemStyleSelector : StyleSelector
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the default <see cref="Style"/>.
|
||||
/// </summary>
|
||||
public Style DefaultStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Style"/> when clickable.
|
||||
/// </summary>
|
||||
public Style ClickableStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SettingsExpanderItemStyleSelector"/> class.
|
||||
/// </summary>
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public SettingsExpanderItemStyleSelector()
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Style SelectStyleCore(object item, DependencyObject container)
|
||||
{
|
||||
if (container is SettingsCard card && card.IsClickEnabled)
|
||||
{
|
||||
return ClickableStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DefaultStyle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.Labs.WinUI.SettingsControls/SettingsCard/SettingsCard.xaml" />
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.Labs.WinUI.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
|
||||
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
|
@ -1,133 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Labs.WinUI;
|
||||
using CommunityToolkit.Tooling.TestGen;
|
||||
using CommunityToolkit.Tests;
|
||||
|
||||
namespace SettingsControlsExperiment.Tests;
|
||||
|
||||
[TestClass]
|
||||
public partial class ExampleSettingsControlsTestClass : VisualUITestBase
|
||||
{
|
||||
// If you don't need access to UI objects directly or async code, use this pattern.
|
||||
[TestMethod]
|
||||
public void SimpleSynchronousExampleTest()
|
||||
{
|
||||
var assembly = typeof(SettingsCard).Assembly;
|
||||
var type = assembly.GetType(typeof(SettingsCard).FullName ?? string.Empty);
|
||||
|
||||
Assert.IsNotNull(type, "Could not find SettingsCard type.");
|
||||
Assert.AreEqual(typeof(SettingsCard), type, "Type of SettingsCard does not match expected type.");
|
||||
}
|
||||
|
||||
// If you don't need access to UI objects directly, use this pattern.
|
||||
[TestMethod]
|
||||
public async Task SimpleAsyncExampleTest()
|
||||
{
|
||||
await Task.Delay(250);
|
||||
|
||||
Assert.IsTrue(true);
|
||||
}
|
||||
|
||||
// Example that shows how to check for exception throwing.
|
||||
[TestMethod]
|
||||
public void SimpleExceptionCheckTest()
|
||||
{
|
||||
// If you need to check exceptions occur for invalid inputs, etc...
|
||||
// Use Assert.ThrowsException to limit the scope to where you expect the error to occur.
|
||||
// Otherwise, using the ExpectedException attribute could swallow or
|
||||
// catch other issues in setup code.
|
||||
Assert.ThrowsException<NotImplementedException>(() => throw new NotImplementedException());
|
||||
}
|
||||
|
||||
// The UIThreadTestMethod automatically dispatches to the UI for us to work with UI objects.
|
||||
[UIThreadTestMethod]
|
||||
public void SimpleUIAttributeExampleTest()
|
||||
{
|
||||
var component = new SettingsCard();
|
||||
Assert.IsNotNull(component);
|
||||
}
|
||||
|
||||
// The UIThreadTestMethod can also easily grab a XAML Page for us by passing its type as a parameter.
|
||||
// This lets us actually test a control as it would behave within an actual application.
|
||||
// The page will already be loaded by the time your test is called.
|
||||
[UIThreadTestMethod]
|
||||
public void SimpleUIExamplePageTest(ExampleSettingsControlsTestPage page)
|
||||
{
|
||||
// You can use the Toolkit Visual Tree helpers here to find the component by type or name:
|
||||
//var component = page.FindDescendant<SettingsCard>();
|
||||
|
||||
//Assert.IsNotNull(component);
|
||||
|
||||
var componentByName = page.FindDescendant("SettingsControlsControl");
|
||||
|
||||
Assert.IsNotNull(componentByName);
|
||||
}
|
||||
|
||||
// You can still do async work with a UIThreadTestMethod as well.
|
||||
[UIThreadTestMethod]
|
||||
public async Task SimpleAsyncUIExamplePageTest(ExampleSettingsControlsTestPage page)
|
||||
{
|
||||
// This helper can be used to wait for a rendering pass to complete.
|
||||
await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });
|
||||
|
||||
var component = page.FindDescendant<SettingsCard>();
|
||||
|
||||
Assert.IsNotNull(component);
|
||||
}
|
||||
|
||||
//// ----------------------------- ADVANCED TEST SCENARIOS -----------------------------
|
||||
|
||||
// If you need to use DataRow, you can use this pattern with the UI dispatch still.
|
||||
// Otherwise, checkout the UIThreadTestMethod attribute above.
|
||||
// See https://github.com/CommunityToolkit/Labs-Windows/issues/186
|
||||
[TestMethod]
|
||||
public async Task ComplexAsyncUIExampleTest()
|
||||
{
|
||||
await EnqueueAsync(() =>
|
||||
{
|
||||
var component = new SettingsCard();
|
||||
Assert.IsNotNull(component);
|
||||
});
|
||||
}
|
||||
|
||||
// If you want to load other content not within a XAML page using the UIThreadTestMethod above.
|
||||
// Then you can do that using the Load/UnloadTestContentAsync methods.
|
||||
[TestMethod]
|
||||
public async Task ComplexAsyncLoadUIExampleTest()
|
||||
{
|
||||
await EnqueueAsync(async () =>
|
||||
{
|
||||
var component = new SettingsCard();
|
||||
Assert.IsNotNull(component);
|
||||
Assert.IsFalse(component.IsLoaded);
|
||||
|
||||
await LoadTestContentAsync(component);
|
||||
|
||||
Assert.IsTrue(component.IsLoaded);
|
||||
|
||||
await UnloadTestContentAsync(component);
|
||||
|
||||
Assert.IsFalse(component.IsLoaded);
|
||||
});
|
||||
}
|
||||
|
||||
// You can still use the UIThreadTestMethod to remove the extra layer for the dispatcher as well:
|
||||
[UIThreadTestMethod]
|
||||
public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest()
|
||||
{
|
||||
var component = new SettingsCard();
|
||||
Assert.IsNotNull(component);
|
||||
Assert.IsFalse(component.IsLoaded);
|
||||
|
||||
await LoadTestContentAsync(component);
|
||||
|
||||
Assert.IsTrue(component.IsLoaded);
|
||||
|
||||
await UnloadTestContentAsync(component);
|
||||
|
||||
Assert.IsFalse(component.IsLoaded);
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
|
||||
<Page x:Class="SettingsControlsExperiment.Tests.ExampleSettingsControlsTestPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<labs:SettingsCard x:Name="SettingsControlsControl" />
|
||||
</Grid>
|
||||
</Page>
|
|
@ -1,16 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace SettingsControlsExperiment.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class ExampleSettingsControlsTestPage : Page
|
||||
{
|
||||
public ExampleSettingsControlsTestPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>D5E2CD55-53B4-49F8-8C2C-0CE2D0DF8457</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>SettingsControlsExperiment.Tests</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ExampleSettingsControlsTestClass.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ExampleSettingsControlsTestPage.xaml.cs">
|
||||
<DependentUpon>ExampleSettingsControlsTestPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="$(MSBuildThisFileDirectory)ExampleSettingsControlsTestPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>D5E2CD55-53B4-49F8-8C2C-0CE2D0DF8457</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<PropertyGroup />
|
||||
<Import Project="SettingsControls.Tests.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче