mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
add Issue Template & add SettingsUI proj
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -4,5 +4,9 @@
|
|||||||
|
|
||||||
.vs/
|
.vs/
|
||||||
|
|
||||||
|
src/SettingsUI/bin
|
||||||
|
src/SettingsUI/obj
|
||||||
|
|
||||||
src/Snap.Hutao/Snap.Hutao/bin/
|
src/Snap.Hutao/Snap.Hutao/bin/
|
||||||
src/Snap.Hutao/Snap.Hutao/obj/
|
src/Snap.Hutao/Snap.Hutao/obj/
|
||||||
|
src/Snap.Hutao/Snap.Hutao/Snap.Hutao_TemporaryKey.pfx
|
||||||
|
|||||||
79
src/SettingsUI/Controls/CheckBoxWithDescriptionControl.cs
Normal file
79
src/SettingsUI/Controls/CheckBoxWithDescriptionControl.cs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace SettingsUI.Controls;
|
||||||
|
|
||||||
|
public class CheckBoxWithDescriptionControl : CheckBox
|
||||||
|
{
|
||||||
|
private CheckBoxWithDescriptionControl _checkBoxSubTextControl;
|
||||||
|
|
||||||
|
public CheckBoxWithDescriptionControl()
|
||||||
|
{
|
||||||
|
_checkBoxSubTextControl = (CheckBoxWithDescriptionControl) this;
|
||||||
|
this.Loaded += CheckBoxSubTextControl_Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
Update();
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Header))
|
||||||
|
{
|
||||||
|
AutomationProperties.SetName(this, Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckBoxSubTextControl_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
StackPanel panel = new StackPanel() { Orientation = Orientation.Vertical };
|
||||||
|
|
||||||
|
// Add text box only if the description is not empty. Required for additional plugin options.
|
||||||
|
if (!string.IsNullOrWhiteSpace(Description))
|
||||||
|
{
|
||||||
|
panel.Children.Add(new TextBlock() { Margin = new Thickness(0, 10, 0, 0), Text = Header });
|
||||||
|
panel.Children.Add(new IsEnabledTextBlock() { Style = (Style) Application.Current.Resources["SecondaryIsEnabledTextBlockStyle"], Text = Description });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panel.Children.Add(new TextBlock() { Margin = new Thickness(0, 0, 0, 0), Text = Header });
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkBoxSubTextControl.Content = panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||||
|
"Header",
|
||||||
|
typeof(string),
|
||||||
|
typeof(CheckBoxWithDescriptionControl),
|
||||||
|
new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||||
|
"Description",
|
||||||
|
typeof(object),
|
||||||
|
typeof(CheckBoxWithDescriptionControl),
|
||||||
|
new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Header
|
||||||
|
{
|
||||||
|
get => (string) GetValue(HeaderProperty);
|
||||||
|
set => SetValue(HeaderProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get => (string) GetValue(DescriptionProperty);
|
||||||
|
set => SetValue(DescriptionProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace SettingsUI.Controls;
|
||||||
|
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
public class IsEnabledTextBlock : Control
|
||||||
|
{
|
||||||
|
public IsEnabledTextBlock()
|
||||||
|
{
|
||||||
|
this.DefaultStyleKey = typeof(IsEnabledTextBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= IsEnabledTextBlock_IsEnabledChanged;
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += IsEnabledTextBlock_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
|
||||||
|
"Text",
|
||||||
|
typeof(string),
|
||||||
|
typeof(IsEnabledTextBlock),
|
||||||
|
null);
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => (string) GetValue(TextProperty);
|
||||||
|
set => SetValue(TextProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IsEnabledTextBlock_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:SettingsUI.Controls">
|
||||||
|
|
||||||
|
<Style TargetType="local:IsEnabledTextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource DefaultTextForegroundThemeBrush}" />
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="local:IsEnabledTextBlock">
|
||||||
|
<Grid>
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="Label.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<TextBlock x:Name="Label"
|
||||||
|
FontSize="{TemplateBinding FontSize}"
|
||||||
|
FontWeight="{TemplateBinding FontWeight}"
|
||||||
|
FontFamily="{TemplateBinding FontFamily}"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Text="{TemplateBinding Text}" />
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="local:IsEnabledTextBlock" x:Key="SecondaryIsEnabledTextBlockStyle">
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource SecondaryTextFontSize}"/>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
156
src/SettingsUI/Controls/Setting/Setting.cs
Normal file
156
src/SettingsUI/Controls/Setting/Setting.cs
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace SettingsUI.Controls;
|
||||||
|
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
[TemplatePart(Name = PartIconPresenter, Type = typeof(ContentPresenter))]
|
||||||
|
[TemplatePart(Name = PartDescriptionPresenter, Type = typeof(ContentPresenter))]
|
||||||
|
public class Setting : ContentControl
|
||||||
|
{
|
||||||
|
private const string PartIconPresenter = "IconPresenter";
|
||||||
|
private const string PartDescriptionPresenter = "DescriptionPresenter";
|
||||||
|
private ContentPresenter _iconPresenter;
|
||||||
|
private ContentPresenter _descriptionPresenter;
|
||||||
|
private Setting _setting;
|
||||||
|
|
||||||
|
public Setting()
|
||||||
|
{
|
||||||
|
this.DefaultStyleKey = typeof(Setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||||
|
"Header",
|
||||||
|
typeof(string),
|
||||||
|
typeof(Setting),
|
||||||
|
new PropertyMetadata(default(string), OnHeaderChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||||
|
"Description",
|
||||||
|
typeof(object),
|
||||||
|
typeof(Setting),
|
||||||
|
new PropertyMetadata(null, OnDescriptionChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
|
||||||
|
"Icon",
|
||||||
|
typeof(object),
|
||||||
|
typeof(Setting),
|
||||||
|
new PropertyMetadata(default(string), OnIconChanged));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ActionContentProperty = DependencyProperty.Register(
|
||||||
|
"ActionContent",
|
||||||
|
typeof(object),
|
||||||
|
typeof(Setting),
|
||||||
|
null);
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Header
|
||||||
|
{
|
||||||
|
get => (string) GetValue(HeaderProperty);
|
||||||
|
set => SetValue(HeaderProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public object Description
|
||||||
|
{
|
||||||
|
get => (object) GetValue(DescriptionProperty);
|
||||||
|
set => SetValue(DescriptionProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Icon
|
||||||
|
{
|
||||||
|
get => (object) GetValue(IconProperty);
|
||||||
|
set => SetValue(IconProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ActionContent
|
||||||
|
{
|
||||||
|
get => (object) GetValue(ActionContentProperty);
|
||||||
|
set => SetValue(ActionContentProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= Setting_IsEnabledChanged;
|
||||||
|
_setting = (Setting) this;
|
||||||
|
_iconPresenter = (ContentPresenter) _setting.GetTemplateChild(PartIconPresenter);
|
||||||
|
_descriptionPresenter = (ContentPresenter) _setting.GetTemplateChild(PartDescriptionPresenter);
|
||||||
|
Update();
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += Setting_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((Setting) d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((Setting) d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((Setting) d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Setting_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_setting == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_setting.ActionContent != null)
|
||||||
|
{
|
||||||
|
if (_setting.ActionContent.GetType() != typeof(Button))
|
||||||
|
{
|
||||||
|
// We do not want to override the default AutomationProperties.Name of a button. Its Content property already describes what it does.
|
||||||
|
if (!string.IsNullOrEmpty(_setting.Header))
|
||||||
|
{
|
||||||
|
AutomationProperties.SetName((UIElement) _setting.ActionContent, _setting.Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_setting._iconPresenter != null)
|
||||||
|
{
|
||||||
|
if (_setting.Icon == null)
|
||||||
|
{
|
||||||
|
_setting._iconPresenter.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_setting._iconPresenter.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_setting.Description == null)
|
||||||
|
{
|
||||||
|
_setting._descriptionPresenter.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_setting._descriptionPresenter.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
107
src/SettingsUI/Controls/Setting/Setting.xaml
Normal file
107
src/SettingsUI/Controls/Setting/Setting.xaml
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:SettingsUI.Controls">
|
||||||
|
|
||||||
|
<Style TargetType="controls:Setting">
|
||||||
|
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}"/>
|
||||||
|
<Setter Property="Background" Value="{ThemeResource CardBackgroundBrush}" />
|
||||||
|
<Setter Property="BorderThickness" Value="{ThemeResource CardBorderThickness}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Padding" Value="16" />
|
||||||
|
<Setter Property="Margin" Value="0,0,0,0"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="controls:Setting">
|
||||||
|
<Grid x:Name="RootGrid"
|
||||||
|
CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Padding="{TemplateBinding Padding}"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
MinHeight="48">
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="HeaderPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="DescriptionPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="IconPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<!-- Icon -->
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<!-- Header and subtitle -->
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<!-- Action control -->
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<ContentPresenter x:Name="IconPresenter"
|
||||||
|
Content="{TemplateBinding Icon}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="20"
|
||||||
|
IsTextScaleFactorEnabled="False"
|
||||||
|
Margin="2,0,18,0"
|
||||||
|
MaxWidth="20"
|
||||||
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||||
|
Foreground="{ThemeResource CardPrimaryForegroundBrush}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Margin="0,0,16,0">
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
x:Name="HeaderPresenter"
|
||||||
|
Text="{TemplateBinding Header}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{ThemeResource CardPrimaryForegroundBrush}" />
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="DescriptionPresenter"
|
||||||
|
Content="{TemplateBinding Description}"
|
||||||
|
FontSize="{StaticResource SecondaryTextFontSize}"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}">
|
||||||
|
<ContentPresenter.Resources>
|
||||||
|
<Style TargetType="TextBlock" BasedOn="{StaticResource CaptionTextBlockStyle}">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="HyperlinkButton" BasedOn="{StaticResource TextButtonStyle}">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="FontSize" Value="12"/>
|
||||||
|
<Setter Property="Padding" Value="0,0,0,0"/>
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
</ContentPresenter.Resources>
|
||||||
|
</ContentPresenter>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="ContentPresenter"
|
||||||
|
Content="{TemplateBinding ActionContent}"
|
||||||
|
Grid.Column="2"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Right" />
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
37
src/SettingsUI/Controls/SettingExpander/SettingExpander.cs
Normal file
37
src/SettingsUI/Controls/SettingExpander/SettingExpander.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace SettingsUI.Controls;
|
||||||
|
|
||||||
|
public partial class SettingExpander : Expander
|
||||||
|
{
|
||||||
|
public SettingExpander()
|
||||||
|
{
|
||||||
|
DefaultStyleKey = typeof(Expander);
|
||||||
|
this.Style = (Style) Application.Current.Resources["SettingExpanderStyle"];
|
||||||
|
this.RegisterPropertyChangedCallback(Expander.HeaderProperty, OnHeaderChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnHeaderChanged(DependencyObject d, DependencyProperty dp)
|
||||||
|
{
|
||||||
|
SettingExpander self = (SettingExpander) d;
|
||||||
|
if (self.Header != null)
|
||||||
|
{
|
||||||
|
if (self.Header.GetType() == typeof(Setting))
|
||||||
|
{
|
||||||
|
Setting selfSetting = (Setting) self.Header;
|
||||||
|
selfSetting.Style = (Style) Application.Current.Resources["ExpanderHeaderSettingStyle"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(selfSetting.Header))
|
||||||
|
{
|
||||||
|
AutomationProperties.SetName(self, selfSetting.Header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
101
src/SettingsUI/Controls/SettingsGroup/SettingsGroup.cs
Normal file
101
src/SettingsUI/Controls/SettingsGroup/SettingsGroup.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Automation.Peers;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace SettingsUI.Controls;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a control that can contain multiple settings (or other) controls
|
||||||
|
/// </summary>
|
||||||
|
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
|
||||||
|
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
|
||||||
|
[TemplatePart(Name = PartDescriptionPresenter, Type = typeof(ContentPresenter))]
|
||||||
|
public partial class SettingsGroup : ItemsControl
|
||||||
|
{
|
||||||
|
private const string PartDescriptionPresenter = "DescriptionPresenter";
|
||||||
|
private ContentPresenter _descriptionPresenter;
|
||||||
|
private SettingsGroup _settingsGroup;
|
||||||
|
|
||||||
|
public SettingsGroup()
|
||||||
|
{
|
||||||
|
DefaultStyleKey = typeof(SettingsGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public string Header
|
||||||
|
{
|
||||||
|
get => (string) GetValue(HeaderProperty);
|
||||||
|
set => SetValue(HeaderProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
||||||
|
"Header",
|
||||||
|
typeof(string),
|
||||||
|
typeof(SettingsGroup),
|
||||||
|
new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
[Localizable(true)]
|
||||||
|
public object Description
|
||||||
|
{
|
||||||
|
get => (object) GetValue(DescriptionProperty);
|
||||||
|
set => SetValue(DescriptionProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||||
|
"Description",
|
||||||
|
typeof(object),
|
||||||
|
typeof(SettingsGroup),
|
||||||
|
new PropertyMetadata(null, OnDescriptionChanged));
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
IsEnabledChanged -= SettingsGroup_IsEnabledChanged;
|
||||||
|
_settingsGroup = (SettingsGroup) this;
|
||||||
|
_descriptionPresenter = (ContentPresenter) _settingsGroup.GetTemplateChild(PartDescriptionPresenter);
|
||||||
|
SetEnabledState();
|
||||||
|
IsEnabledChanged += SettingsGroup_IsEnabledChanged;
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((SettingsGroup) d).Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SettingsGroup_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
SetEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEnabledState()
|
||||||
|
{
|
||||||
|
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_settingsGroup == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_settingsGroup.Description == null)
|
||||||
|
{
|
||||||
|
_settingsGroup._descriptionPresenter.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_settingsGroup._descriptionPresenter.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override AutomationPeer OnCreateAutomationPeer()
|
||||||
|
{
|
||||||
|
return new SettingsGroupAutomationPeer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/SettingsUI/Controls/SettingsGroup/SettingsGroup.xaml
Normal file
71
src/SettingsUI/Controls/SettingsGroup/SettingsGroup.xaml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:SettingsUI.Controls">
|
||||||
|
|
||||||
|
<Style TargetType="controls:SettingsGroup">
|
||||||
|
<Setter Property="ItemsPanel">
|
||||||
|
<Setter.Value>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
Spacing="2"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="controls:SettingsGroup">
|
||||||
|
<Grid HorizontalAlignment="Stretch">
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal"/>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="HeaderPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
<Setter Target="DescriptionPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
</VisualState>
|
||||||
|
</VisualStateGroup>
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock x:Name="HeaderPresenter"
|
||||||
|
Text="{TemplateBinding Header}"
|
||||||
|
Grid.Row="0"
|
||||||
|
Style="{ThemeResource BodyStrongTextBlockStyle}"
|
||||||
|
Margin="1,32,0,0"
|
||||||
|
AutomationProperties.HeadingLevel="Level2"/>
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="DescriptionPresenter"
|
||||||
|
Content="{TemplateBinding Description}"
|
||||||
|
TextWrapping="WrapWholeWords"
|
||||||
|
Margin="1,4,0,0"
|
||||||
|
Grid.Row="1"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}">
|
||||||
|
<ContentPresenter.Resources>
|
||||||
|
<Style TargetType="TextBlock" BasedOn="{StaticResource CaptionTextBlockStyle}">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="HyperlinkButton" BasedOn="{StaticResource TextButtonStyle}">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="Padding" Value="0,0,0,0"/>
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
</ContentPresenter.Resources>
|
||||||
|
</ContentPresenter>
|
||||||
|
<ItemsPresenter Grid.Row="2" Margin="0,8,0,0"/>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml.Automation.Peers;
|
||||||
|
|
||||||
|
namespace SettingsUI.Controls;
|
||||||
|
|
||||||
|
public class SettingsGroupAutomationPeer : FrameworkElementAutomationPeer
|
||||||
|
{
|
||||||
|
public SettingsGroupAutomationPeer(SettingsGroup owner)
|
||||||
|
: base(owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string GetNameCore()
|
||||||
|
{
|
||||||
|
var selectedSettingsGroup = (SettingsGroup) Owner;
|
||||||
|
return selectedSettingsGroup.Header;
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/SettingsUI/SettingsUI.csproj
Normal file
51
src/SettingsUI/SettingsUI.csproj
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net6.0-windows10.0.17763.0</TargetFrameworks>
|
||||||
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
|
<RootNamespace>SettingsUI</RootNamespace>
|
||||||
|
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
|
<UseWinUI>true</UseWinUI>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.0.3" />
|
||||||
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22000.197" />
|
||||||
|
<PackageReference Include="nucs.JsonSettings" Version="2.0.0-alpha7" />
|
||||||
|
<PackageReference Include="nucs.JsonSettings.Autosave" Version="2.0.0-alpha7" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\IsEnabledTextBlock\IsEnabledTextBlock.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Controls\SettingsGroup\SettingsGroup.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Controls\Setting\Setting.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Styles\Button.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Styles\Common.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Styles\TextBlock.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Themes\Colors.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Themes\Generic.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Themes\SettingsExpanderStyles.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Update="Themes\SettingsUI.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
581
src/SettingsUI/Styles/Button.xaml
Normal file
581
src/SettingsUI/Styles/Button.xaml
Normal file
@@ -0,0 +1,581 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)"
|
||||||
|
xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)">
|
||||||
|
|
||||||
|
<Style x:Key="SettingButtonStyle" TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}" >
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}" />
|
||||||
|
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||||
|
<Setter Property="Padding" Value="16,0,16,0" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="HyperlinkButtonStyle" TargetType="HyperlinkButton" >
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="TextButtonStyle" TargetType="ButtonBase">
|
||||||
|
<Setter Property="Background" Value="{ThemeResource HyperlinkButtonBackground}" />
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource HyperlinkButtonForeground}" />
|
||||||
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
<Setter Property="MinHeight" Value="0" />
|
||||||
|
<Setter Property="Margin" Value="0" />
|
||||||
|
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ButtonBase">
|
||||||
|
<Grid Margin="{TemplateBinding Padding}" CornerRadius="4" Background="{TemplateBinding Background}">
|
||||||
|
<ContentPresenter x:Name="Text"
|
||||||
|
Content="{TemplateBinding Content}"
|
||||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||||
|
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal" />
|
||||||
|
|
||||||
|
<VisualState x:Name="PointerOver">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="BorderBrush">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
<VisualState x:Name="Pressed">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="BorderBrush">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonForegroundDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBackgroundDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="BorderBrush">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource HyperlinkButtonBorderBrushDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
</VisualStateGroup>
|
||||||
|
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- This style overrides the default style so that all ToggleSwitches are right aligned, with the label on the left -->
|
||||||
|
<Style x:Key="ToggleSwitchSettingStyle" TargetType="ToggleSwitch">
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource ToggleSwitchContentForeground}" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Right" />
|
||||||
|
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||||
|
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||||
|
<Setter Property="ManipulationMode" Value="System,TranslateX" />
|
||||||
|
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||||
|
|
||||||
|
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ToggleSwitch">
|
||||||
|
<Grid
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
contract7Present:CornerRadius="{TemplateBinding CornerRadius}">
|
||||||
|
|
||||||
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<VisualStateGroup x:Name="CommonStates">
|
||||||
|
<VisualState x:Name="Normal">
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Stroke">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOff}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOff}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOff}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOn}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOn}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOn}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContainerBackground}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="PointerOver">
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffPointerOver}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffPointerOver}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnPointerOver}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundPointerOver}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="Pressed">
|
||||||
|
|
||||||
|
<VisualState.Setters>
|
||||||
|
<Setter Target="SwitchKnobOn.HorizontalAlignment" Value="Right" />
|
||||||
|
<Setter Target="SwitchKnobOn.Margin" Value="0,0,3,0" />
|
||||||
|
<Setter Target="SwitchKnobOff.HorizontalAlignment" Value="Left" />
|
||||||
|
<Setter Target="SwitchKnobOff.Margin" Value="3,0,0,0" />
|
||||||
|
</VisualState.Setters>
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffPressed}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffPressed}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnPressed}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundPressed}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="17" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="17" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="14" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="Disabled">
|
||||||
|
<Storyboard>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchHeaderForegroundDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OffContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContentForegroundDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OnContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchContentForegroundDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchStrokeOffDisabled}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchFillOffDisabled}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchFillOnDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Stroke">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchStrokeOnDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Fill">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOffDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Background">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ToggleSwitchKnobFillOnDisabled}" />
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
<ColorAnimationUsingKeyFrames Storyboard.TargetName="SwitchAreaGrid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
|
||||||
|
<LinearColorKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="{ThemeResource ToggleSwitchContainerBackgroundDisabled}" />
|
||||||
|
</ColorAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Width" EnableDependentAnimation="True" >
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Width" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Height" EnableDependentAnimation="True">
|
||||||
|
<SplineDoubleKeyFrame KeyTime="{StaticResource ControlNormalAnimationDuration}" KeySpline="{StaticResource ControlFastOutSlowInKeySpline}" Value="12" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
</VisualStateGroup>
|
||||||
|
<VisualStateGroup x:Name="ToggleStates">
|
||||||
|
|
||||||
|
<VisualStateGroup.Transitions>
|
||||||
|
<VisualTransition x:Name="DraggingToOnTransition"
|
||||||
|
From="Dragging"
|
||||||
|
To="On"
|
||||||
|
GeneratedDuration="0">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobCurrentToOnOffset}" />
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualTransition>
|
||||||
|
<VisualTransition x:Name="OnToDraggingTransition"
|
||||||
|
From="On"
|
||||||
|
To="Dragging"
|
||||||
|
GeneratedDuration="0">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="0" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="0" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="0" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualTransition>
|
||||||
|
<VisualTransition x:Name="DraggingToOffTransition"
|
||||||
|
From="Dragging"
|
||||||
|
To="Off"
|
||||||
|
GeneratedDuration="0">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobCurrentToOffOffset}" />
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualTransition>
|
||||||
|
<VisualTransition x:Name="OnToOffTransition"
|
||||||
|
From="On"
|
||||||
|
To="Off"
|
||||||
|
GeneratedDuration="0">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobOnToOffOffset}" />
|
||||||
|
</Storyboard>
|
||||||
|
</VisualTransition>
|
||||||
|
<VisualTransition x:Name="OffToOnTransition"
|
||||||
|
From="Off"
|
||||||
|
To="On"
|
||||||
|
GeneratedDuration="0">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<RepositionThemeAnimation TargetName="SwitchKnob" FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KnobOffToOnOffset}"/>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualTransition>
|
||||||
|
</VisualStateGroup.Transitions>
|
||||||
|
<VisualState x:Name="Dragging" />
|
||||||
|
<VisualState x:Name="Off" />
|
||||||
|
<VisualState x:Name="On">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="KnobTranslateTransform"
|
||||||
|
Storyboard.TargetProperty="X"
|
||||||
|
To="20"
|
||||||
|
Duration="0" />
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobBounds" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="OuterBorder" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOn" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchKnobOff" Storyboard.TargetProperty="Opacity">
|
||||||
|
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0" />
|
||||||
|
</DoubleAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
</VisualStateGroup>
|
||||||
|
<VisualStateGroup x:Name="ContentStates">
|
||||||
|
<VisualState x:Name="OffContent">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="OffContentPresenter"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
To="1"
|
||||||
|
Duration="0" />
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="OffContentPresenter">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0">
|
||||||
|
<DiscreteObjectKeyFrame.Value>
|
||||||
|
<x:Boolean>True</x:Boolean>
|
||||||
|
</DiscreteObjectKeyFrame.Value>
|
||||||
|
</DiscreteObjectKeyFrame>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
<VisualState x:Name="OnContent">
|
||||||
|
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="OnContentPresenter"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
To="1"
|
||||||
|
Duration="0" />
|
||||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="OnContentPresenter">
|
||||||
|
<DiscreteObjectKeyFrame KeyTime="0">
|
||||||
|
<DiscreteObjectKeyFrame.Value>
|
||||||
|
<x:Boolean>True</x:Boolean>
|
||||||
|
</DiscreteObjectKeyFrame.Value>
|
||||||
|
</DiscreteObjectKeyFrame>
|
||||||
|
</ObjectAnimationUsingKeyFrames>
|
||||||
|
</Storyboard>
|
||||||
|
</VisualState>
|
||||||
|
|
||||||
|
</VisualStateGroup>
|
||||||
|
|
||||||
|
</VisualStateManager.VisualStateGroups>
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<ContentPresenter x:Name="HeaderContentPresenter"
|
||||||
|
x:DeferLoadStrategy="Lazy"
|
||||||
|
Grid.Row="0"
|
||||||
|
Content="{TemplateBinding Header}"
|
||||||
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
|
Foreground="{ThemeResource ToggleSwitchHeaderForeground}"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
Margin="{ThemeResource ToggleSwitchTopHeaderMargin}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Visibility="Collapsed"
|
||||||
|
AutomationProperties.AccessibilityView="Raw" />
|
||||||
|
<Grid
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Top">
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="{ThemeResource ToggleSwitchPreContentMargin}" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="{ThemeResource ToggleSwitchPostContentMargin}" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="12" MaxWidth="12" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid x:Name="SwitchAreaGrid"
|
||||||
|
Grid.RowSpan="3"
|
||||||
|
Grid.ColumnSpan="3"
|
||||||
|
Margin="0,5"
|
||||||
|
contract7Present:CornerRadius="{TemplateBinding CornerRadius}"
|
||||||
|
contract7NotPresent:CornerRadius="{StaticResource ControlCornerRadius}"
|
||||||
|
Control.IsTemplateFocusTarget="True"
|
||||||
|
Background="{ThemeResource ToggleSwitchContainerBackground}" />
|
||||||
|
<ContentPresenter x:Name="OffContentPresenter"
|
||||||
|
Grid.RowSpan="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Opacity="0"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
Content="{TemplateBinding OffContent}"
|
||||||
|
ContentTemplate="{TemplateBinding OffContentTemplate}"
|
||||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
|
AutomationProperties.AccessibilityView="Raw" />
|
||||||
|
<ContentPresenter x:Name="OnContentPresenter"
|
||||||
|
Grid.RowSpan="3"
|
||||||
|
Grid.Column="0"
|
||||||
|
Opacity="0"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
Content="{TemplateBinding OnContent}"
|
||||||
|
ContentTemplate="{TemplateBinding OnContentTemplate}"
|
||||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
|
AutomationProperties.AccessibilityView="Raw" />
|
||||||
|
<Rectangle x:Name="OuterBorder"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="2"
|
||||||
|
Height="20"
|
||||||
|
Width="40"
|
||||||
|
RadiusX="10"
|
||||||
|
RadiusY="10"
|
||||||
|
Fill="{ThemeResource ToggleSwitchFillOff}"
|
||||||
|
Stroke="{ThemeResource ToggleSwitchStrokeOff}"
|
||||||
|
StrokeThickness="{ThemeResource ToggleSwitchOuterBorderStrokeThickness}" />
|
||||||
|
<Rectangle x:Name="SwitchKnobBounds"
|
||||||
|
Grid.Row="1"
|
||||||
|
Height="20"
|
||||||
|
Width="40"
|
||||||
|
RadiusX="10"
|
||||||
|
RadiusY="10"
|
||||||
|
Grid.Column="2"
|
||||||
|
Fill="{ThemeResource ToggleSwitchFillOn}"
|
||||||
|
Stroke="{ThemeResource ToggleSwitchStrokeOn}"
|
||||||
|
StrokeThickness="{ThemeResource ToggleSwitchOnStrokeThickness}"
|
||||||
|
Opacity="0" />
|
||||||
|
<Grid x:Name="SwitchKnob"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="2"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Width="20"
|
||||||
|
Height="20">
|
||||||
|
<Border x:Name="SwitchKnobOn"
|
||||||
|
Background="{ThemeResource ToggleSwitchKnobFillOn}"
|
||||||
|
BorderBrush="{ThemeResource ToggleSwitchKnobStrokeOn}"
|
||||||
|
contract7Present:BackgroundSizing="OuterBorderEdge"
|
||||||
|
Width="12"
|
||||||
|
Height="12"
|
||||||
|
CornerRadius="7"
|
||||||
|
Grid.Column="2"
|
||||||
|
Opacity="0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,0,1,0"
|
||||||
|
RenderTransformOrigin="0.5, 0.5">
|
||||||
|
<Border.RenderTransform>
|
||||||
|
<CompositeTransform/>
|
||||||
|
</Border.RenderTransform>
|
||||||
|
</Border>
|
||||||
|
<Rectangle x:Name="SwitchKnobOff"
|
||||||
|
Fill="{ThemeResource ToggleSwitchKnobFillOff}"
|
||||||
|
Width="12"
|
||||||
|
Height="12"
|
||||||
|
RadiusX="7"
|
||||||
|
Grid.Column="2"
|
||||||
|
RadiusY="7"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="-1,0,0,0"
|
||||||
|
RenderTransformOrigin="0.5, 0.5">
|
||||||
|
<Rectangle.RenderTransform>
|
||||||
|
<CompositeTransform/>
|
||||||
|
</Rectangle.RenderTransform>
|
||||||
|
</Rectangle>
|
||||||
|
<Grid.RenderTransform>
|
||||||
|
<TranslateTransform x:Name="KnobTranslateTransform" />
|
||||||
|
</Grid.RenderTransform>
|
||||||
|
</Grid>
|
||||||
|
<Thumb x:Name="SwitchThumb"
|
||||||
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
Grid.RowSpan="3"
|
||||||
|
Grid.ColumnSpan="3">
|
||||||
|
<Thumb.Template>
|
||||||
|
<ControlTemplate TargetType="Thumb">
|
||||||
|
<Rectangle Fill="Transparent" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Thumb.Template>
|
||||||
|
</Thumb>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
15
src/SettingsUI/Styles/Common.xaml
Normal file
15
src/SettingsUI/Styles/Common.xaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:controls="using:SettingsUI.Controls"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style x:Key="ListViewItemSettingStyle" TargetType="ListViewItem">
|
||||||
|
<Setter Property="Margin" Value="0,0,0,2" />
|
||||||
|
<Setter Property="Padding" Value="0,0,0,0" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style
|
||||||
|
TargetType="controls:CheckBoxWithDescriptionControl"
|
||||||
|
BasedOn="{StaticResource DefaultCheckBoxStyle}" />
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
22
src/SettingsUI/Styles/TextBlock.xaml
Normal file
22
src/SettingsUI/Styles/TextBlock.xaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style x:Key="OobeSubtitleStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="Margin" Value="0,16,0,0" />
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource DefaultTextForegroundThemeBrush}" />
|
||||||
|
<Setter Property="AutomationProperties.HeadingLevel" Value="Level3" />
|
||||||
|
<Setter Property="FontFamily" Value="XamlAutoFontFamily" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource BodyTextBlockFontSize}" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
|
||||||
|
<Setter Property="TextWrapping" Value="Wrap" />
|
||||||
|
<Setter Property="LineStackingStrategy" Value="MaxHeight" />
|
||||||
|
<Setter Property="TextLineBounds" Value="Full" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<x:Double x:Key="SecondaryTextFontSize">12</x:Double>
|
||||||
|
<Style x:Key="SecondaryTextStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource SecondaryTextFontSize}"/>
|
||||||
|
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondaryBrush}"/>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
32
src/SettingsUI/Themes/Colors.xaml
Normal file
32
src/SettingsUI/Themes/Colors.xaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Key="Dark">
|
||||||
|
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="CardBackgroundFillColorDefaultBrush" />
|
||||||
|
<StaticResource x:Key="CardBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||||
|
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
|
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="#FF34424d"/>
|
||||||
|
<Color x:Key="InfoBarInformationalSeverityIconBackground">#FF5fb2f2</Color>
|
||||||
|
<Thickness x:Key="CardBorderThickness">1</Thickness>
|
||||||
|
</ResourceDictionary>
|
||||||
|
|
||||||
|
<ResourceDictionary x:Key="Light">
|
||||||
|
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="CardBackgroundFillColorDefaultBrush" />
|
||||||
|
<StaticResource x:Key="CardBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||||
|
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
|
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="#FFd3e7f7"/>
|
||||||
|
<Color x:Key="InfoBarInformationalSeverityIconBackground">#FF0063b1</Color>
|
||||||
|
<Thickness x:Key="CardBorderThickness">1</Thickness>
|
||||||
|
</ResourceDictionary>
|
||||||
|
|
||||||
|
<ResourceDictionary x:Key="HighContrast">
|
||||||
|
<StaticResource x:Key="CardBackgroundBrush" ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||||
|
<StaticResource x:Key="CardBorderBrush" ResourceKey="SystemColorButtonTextColorBrush" />
|
||||||
|
<StaticResource x:Key="CardPrimaryForegroundBrush" ResourceKey="SystemColorButtonTextColorBrush" />
|
||||||
|
<SolidColorBrush x:Key="InfoBarInformationalSeverityBackgroundBrush" Color="#FF34424d"/>
|
||||||
|
<Color x:Key="InfoBarInformationalSeverityIconBackground">#FF5fb2f2</Color>
|
||||||
|
<Thickness x:Key="CardBorderThickness">2</Thickness>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
9
src/SettingsUI/Themes/Generic.xaml
Normal file
9
src/SettingsUI/Themes/Generic.xaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="ms-appx:///SettingsUI/Controls/Setting/Setting.xaml" />
|
||||||
|
<ResourceDictionary Source="ms-appx:///SettingsUI/Controls/SettingsGroup/SettingsGroup.xaml" />
|
||||||
|
<ResourceDictionary Source="ms-appx:///SettingsUI/Controls/IsEnabledTextBlock/IsEnabledTextBlock.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
52
src/SettingsUI/Themes/SettingsExpanderStyles.xaml
Normal file
52
src/SettingsUI/Themes/SettingsExpanderStyles.xaml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:SettingsUI.Controls">
|
||||||
|
|
||||||
|
<!-- Thickness -->
|
||||||
|
<Thickness x:Key="ExpanderContentPadding">0</Thickness>
|
||||||
|
<Thickness x:Key="ExpanderSettingMargin">56, 8, 40, 8</Thickness>
|
||||||
|
|
||||||
|
<SolidColorBrush x:Key="ExpanderChevronPointerOverBackground">Transparent</SolidColorBrush>
|
||||||
|
|
||||||
|
<!-- Styles -->
|
||||||
|
<!-- Setting used in a Expander header -->
|
||||||
|
<Style x:Key="ExpanderHeaderSettingStyle"
|
||||||
|
TargetType="controls:Setting">
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent" />
|
||||||
|
<Setter Property="Padding" Value="0,14,0,14" />
|
||||||
|
<Setter Property="Margin" Value="0" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Thickness x:Key="ExpanderChevronMargin">0,0,8,0</Thickness>
|
||||||
|
|
||||||
|
<!-- Setting used in a Expander header -->
|
||||||
|
<Style x:Key="ExpanderContentSettingStyle"
|
||||||
|
TargetType="controls:Setting">
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="BorderThickness" Value="0,1,0,0" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}" />
|
||||||
|
<Setter Property="CornerRadius" Value="0" />
|
||||||
|
<Setter Property="Padding" Value="{StaticResource ExpanderSettingMargin}" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Setting expander style -->
|
||||||
|
<Style x:Key="SettingExpanderStyle"
|
||||||
|
TargetType="Expander">
|
||||||
|
<Setter Property="Background" Value="{ThemeResource CardBackgroundBrush}" />
|
||||||
|
<Setter Property="BorderThickness" Value="{ThemeResource CardBorderThickness}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{ThemeResource CardBorderBrush}" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="ExpanderSeparatorStyle"
|
||||||
|
TargetType="Rectangle">
|
||||||
|
<Setter Property="Height" Value="1" />
|
||||||
|
<Setter Property="Stroke" Value="{ThemeResource CardBorderBrush}" />
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
14
src/SettingsUI/Themes/SettingsUI.xaml
Normal file
14
src/SettingsUI/Themes/SettingsUI.xaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<ResourceDictionary
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="../Styles/Common.xaml"/>
|
||||||
|
<ResourceDictionary Source="../Styles/TextBlock.xaml"/>
|
||||||
|
<ResourceDictionary Source="../Styles/Button.xaml"/>
|
||||||
|
<ResourceDictionary Source="../Themes/Colors.xaml"/>
|
||||||
|
<ResourceDictionary Source="../Themes/SettingsExpanderStyles.xaml"/>
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<x:Double x:Key="SettingActionControlMinWidth">240</x:Double>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -79,6 +79,18 @@ dotnet_naming_style.pascal_case.capitalization = pascal_case
|
|||||||
dotnet_diagnostic.SA1629.severity = silent
|
dotnet_diagnostic.SA1629.severity = silent
|
||||||
dotnet_diagnostic.SA1642.severity = silent
|
dotnet_diagnostic.SA1642.severity = silent
|
||||||
|
|
||||||
|
# SA1208: System using directives should be placed before other using directives
|
||||||
|
dotnet_diagnostic.SA1208.severity = none
|
||||||
|
|
||||||
|
# SA1404: Code analysis suppression should have justification
|
||||||
|
dotnet_diagnostic.SA1404.severity = none
|
||||||
|
|
||||||
|
# SA1623: Property summary documentation should match accessors
|
||||||
|
dotnet_diagnostic.SA1623.severity = none
|
||||||
|
|
||||||
|
# SA1636: File header copyright text should match
|
||||||
|
dotnet_diagnostic.SA1636.severity = none
|
||||||
|
|
||||||
[*.vb]
|
[*.vb]
|
||||||
#### 命名样式 ####
|
#### 命名样式 ####
|
||||||
|
|
||||||
|
|||||||
62
src/Snap.Hutao/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
62
src/Snap.Hutao/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
name: 问题反馈
|
||||||
|
description: 告诉我们你的问题
|
||||||
|
title: "[Bug]: 取一个合适的标题"
|
||||||
|
labels: ["BUG"]
|
||||||
|
assignees:
|
||||||
|
- Lightczx
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
请按下方的要求填写完整的问题表单,以便我们更快的定位问题。
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: winver
|
||||||
|
attributes:
|
||||||
|
label: Windows 版本
|
||||||
|
description: |
|
||||||
|
`Win+R` 输入 `winver` 回车后在打开的窗口第二行可以找到
|
||||||
|
placeholder: 例:22000.556
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: shver
|
||||||
|
attributes:
|
||||||
|
label: Snap Hutao 版本
|
||||||
|
description: 在应用程序的设置界面中靠下的位置可以找到
|
||||||
|
placeholder: 例:2022.3.23.1
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: shuuid
|
||||||
|
attributes:
|
||||||
|
label: Snap Hutao 用户设备ID
|
||||||
|
description: 在应用程序的设置界面中靠下的位置可以找到,并可以通过右侧按钮复制
|
||||||
|
placeholder: 此ID不包含敏感信息,可以放心填写
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: 发生了什么?
|
||||||
|
description: 详细的描述问题发生前后的行为,以便我们解决问题
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: what-expected
|
||||||
|
attributes:
|
||||||
|
label: 你期望发生的行为?
|
||||||
|
description: 详细的描述你期望发生的行为,突出与目前(可能不正确的)行为的不同
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: 相关的崩溃日志
|
||||||
|
description: 如果应用程序崩溃了,可以将崩溃日志复制后粘贴在此处
|
||||||
|
render: shell
|
||||||
9
src/Snap.Hutao/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
9
src/Snap.Hutao/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: 问题与操作指南文档
|
||||||
|
url: https://www.snapgenshin.com/documents/
|
||||||
|
about: 在发起 Issue 前 请查阅此文档确认文档中尚未包含你的问题的解决方案
|
||||||
|
- name: 功能建议
|
||||||
|
url: https://github.com/DGP-Studio/Snap.Genshin/discussions
|
||||||
|
about: Issues 仅用于反馈与追踪 Bug
|
||||||
19
src/Snap.Hutao/.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
19
src/Snap.Hutao/.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: 功能请求
|
||||||
|
description: 告诉我们你的想法
|
||||||
|
title: "[Feat]: 取一个合适的标题"
|
||||||
|
labels: ["功能"]
|
||||||
|
assignees:
|
||||||
|
- Lightczx
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
请按下方的要求填写完整的问题表单,以便我们更快的定位问题。
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: req
|
||||||
|
attributes:
|
||||||
|
label: 你想要实现或优化的功能?
|
||||||
|
description: 详细的描述一下你想要的功能
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
@@ -10,9 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{F5886EF9-4D7D-46AF-B2E0-5D1825B6ECCF}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SettingsUI", "..\SettingsUI\SettingsUI.csproj", "{FC2E96B6-775E-465C-82FB-9931826C8049}"
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Core.Mvvm", "Common\Snap.Core.Mvvm\Snap.Core.Mvvm.csproj", "{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -50,29 +48,26 @@ Global
|
|||||||
{AAAB7CF0-F299-49B8-BDB4-4C320B3EC2C7}.Release|x86.ActiveCfg = Release|x86
|
{AAAB7CF0-F299-49B8-BDB4-4C320B3EC2C7}.Release|x86.ActiveCfg = Release|x86
|
||||||
{AAAB7CF0-F299-49B8-BDB4-4C320B3EC2C7}.Release|x86.Build.0 = Release|x86
|
{AAAB7CF0-F299-49B8-BDB4-4C320B3EC2C7}.Release|x86.Build.0 = Release|x86
|
||||||
{AAAB7CF0-F299-49B8-BDB4-4C320B3EC2C7}.Release|x86.Deploy.0 = Release|x86
|
{AAAB7CF0-F299-49B8-BDB4-4C320B3EC2C7}.Release|x86.Deploy.0 = Release|x86
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|arm64.ActiveCfg = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|arm64.ActiveCfg = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|arm64.Build.0 = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|arm64.Build.0 = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|x64.Build.0 = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Debug|x86.Build.0 = Debug|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|Any CPU.Build.0 = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|arm64.ActiveCfg = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|arm64.ActiveCfg = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|arm64.Build.0 = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|arm64.Build.0 = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|x64.ActiveCfg = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|x64.Build.0 = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|x86.ActiveCfg = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C}.Release|x86.Build.0 = Release|Any CPU
|
{FC2E96B6-775E-465C-82FB-9931826C8049}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{62CEF8A4-4F38-4EC5-9FFD-B9C767AFAB8C} = {F5886EF9-4D7D-46AF-B2E0-5D1825B6ECCF}
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {E4449B1C-0E6A-4D19-955E-1CA491656ABA}
|
SolutionGuid = {E4449B1C-0E6A-4D19-955E-1CA491656ABA}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
<Application
|
<Application
|
||||||
x:Class="Snap.Hutao.App"
|
x:Class="Snap.Hutao.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
xmlns:local="using:Snap.Hutao">
|
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||||
<!-- Other merged dictionaries here -->
|
<ResourceDictionary Source="ms-appx:///SettingsUI/Themes/SettingsUI.xaml"/>
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
<!-- Other app resources here -->
|
<!-- Other app resources here -->
|
||||||
|
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
|
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
|
<StaticResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||||
|
<StaticResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) DGP Studio. All rights reserved.
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
|
|
||||||
namespace Snap.Hutao;
|
namespace Snap.Hutao;
|
||||||
@@ -10,25 +12,33 @@ namespace Snap.Hutao;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
private Window mainWindow;
|
private Window? mainWindow;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the singleton application object. This is the first line of authored code
|
/// Initializes the singleton application object.
|
||||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
/// This is the first line of authored code executed, and as such is the logical equivalent of main() or WinMain().
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
|
// load app resource
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
// prepare DI
|
||||||
|
Ioc.Default.ConfigureServices(new ServiceCollection()
|
||||||
|
.AddLogging(builder => builder.AddDebug())
|
||||||
|
.AddHttpClient()
|
||||||
|
.AddInjections(typeof(App))
|
||||||
|
.BuildServiceProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
/// Invoked when the application is launched normally by the end user.
|
||||||
/// will be used such as when the application is launched to open a specific file.
|
/// Other entry points will be used such as when the application is launched to open a specific file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">Details about the launch request and process.</param>
|
/// <param name="args">Details about the launch request and process.</param>
|
||||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
mainWindow = new MainWindow();
|
mainWindow = Ioc.Default.GetRequiredService<MainWindow>();
|
||||||
mainWindow.Activate();
|
mainWindow.Activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core.DependencyInjection.Annotation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示被标注的类型可注入
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||||
|
public class InjectionAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 指示该类将注入为不带有接口实现的类
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="injectAs">指示注入方法</param>
|
||||||
|
public InjectionAttribute(InjectAs injectAs)
|
||||||
|
{
|
||||||
|
InjectAs = injectAs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示该类将注入为带有接口实现的类
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="injectAs">指示注入方法</param>
|
||||||
|
/// <param name="impl">实现的接口类型</param>
|
||||||
|
public InjectionAttribute(InjectAs injectAs, Type impl)
|
||||||
|
{
|
||||||
|
InterfaceType = impl;
|
||||||
|
InjectAs = injectAs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注入类型
|
||||||
|
/// </summary>
|
||||||
|
public InjectAs InjectAs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 该类实现的接口类型
|
||||||
|
/// </summary>
|
||||||
|
public Type? InterfaceType { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Snap.Hutao.Core.DependencyInjection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注入方法
|
||||||
|
/// </summary>
|
||||||
|
public enum InjectAs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 指示应注册为单例对象
|
||||||
|
/// </summary>
|
||||||
|
Singleton,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示应注册为短期对象
|
||||||
|
/// </summary>
|
||||||
|
Transient,
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Snap.Hutao.Core.DependencyInjection.Annotation;
|
||||||
|
using Snap.Hutao.Core.Validation;
|
||||||
|
using Snap.Hutao.Extension;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core.DependencyInjection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务管理器
|
||||||
|
/// 依赖注入的核心管理类
|
||||||
|
/// </summary>
|
||||||
|
internal static class ServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 向容器注册服务, 调用 <see cref="Register(IServiceCollection, Type)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">容器</param>
|
||||||
|
/// <param name="entryType">入口类型,该类型所在的程序集均会被扫描</param>
|
||||||
|
/// <returns>可继续操作的服务集合</returns>
|
||||||
|
public static IServiceCollection AddInjections(this IServiceCollection services, Type entryType)
|
||||||
|
{
|
||||||
|
entryType.Assembly.ForEachType(type => Register(services, type));
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向容器注册类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">容器</param>
|
||||||
|
/// <param name="type">待检测的类型</param>
|
||||||
|
/// <returns>可继续操作的服务集合</returns>
|
||||||
|
public static IServiceCollection Register(this IServiceCollection services, Type type)
|
||||||
|
{
|
||||||
|
if (type.TryGetAttribute(out InjectionAttribute? attr))
|
||||||
|
{
|
||||||
|
if (attr.InterfaceType is not null)
|
||||||
|
{
|
||||||
|
return attr.InjectAs switch
|
||||||
|
{
|
||||||
|
InjectAs.Singleton => services.AddSingleton(attr.InterfaceType, type),
|
||||||
|
InjectAs.Transient => services.AddTransient(attr.InterfaceType, type),
|
||||||
|
_ => Must.NeverHappen<IServiceCollection>(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return attr.InjectAs switch
|
||||||
|
{
|
||||||
|
InjectAs.Singleton => services.AddSingleton(type),
|
||||||
|
InjectAs.Transient => services.AddTransient(type),
|
||||||
|
_ => throw Must.NeverHappen(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/Snap.Hutao/Snap.Hutao/Core/Logging/EventIds.cs
Normal file
17
src/Snap.Hutao/Snap.Hutao/Core/Logging/EventIds.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core.Logging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 事件Id定义
|
||||||
|
/// </summary>
|
||||||
|
internal static class EventIds
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 导航失败
|
||||||
|
/// </summary>
|
||||||
|
public static readonly EventId NavigationFailed = new(100000, "NavigationFailed");
|
||||||
|
}
|
||||||
84
src/Snap.Hutao/Snap.Hutao/Core/Property.cs
Normal file
84
src/Snap.Hutao/Snap.Hutao/Core/Property.cs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 快速创建 <see cref="TOwner"/> 的 <see cref="DependencyProperty"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TOwner">所有者的类型</typeparam>
|
||||||
|
internal static class Property<TOwner>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注册依赖属性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <returns>注册的依赖属性</returns>
|
||||||
|
public static DependencyProperty Depend<TProperty>(string name)
|
||||||
|
{
|
||||||
|
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new PropertyMetadata(default(TProperty)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册依赖属性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <param name="defaultValue">默认值</param>
|
||||||
|
/// <returns>注册的依赖属性</returns>
|
||||||
|
public static DependencyProperty Depend<TProperty>(string name, TProperty defaultValue)
|
||||||
|
{
|
||||||
|
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new PropertyMetadata(defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册依赖属性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <param name="defaultValue">默认值</param>
|
||||||
|
/// <param name="callback">属性更改回调</param>
|
||||||
|
/// <returns>注册的依赖属性</returns>
|
||||||
|
public static DependencyProperty Depend<TProperty>(string name, TProperty defaultValue, PropertyChangedCallback callback)
|
||||||
|
{
|
||||||
|
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new PropertyMetadata(defaultValue, callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册附加属性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <returns>注册的附加属性</returns>
|
||||||
|
public static DependencyProperty Attach<TProperty>(string name)
|
||||||
|
{
|
||||||
|
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new PropertyMetadata(default(TProperty)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册附加属性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <param name="defaultValue">默认值</param>
|
||||||
|
/// <returns>注册的附加属性</returns>
|
||||||
|
public static DependencyProperty Attach<TProperty>(string name, TProperty defaultValue)
|
||||||
|
{
|
||||||
|
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new PropertyMetadata(defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册附加属性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <param name="callback">属性更改回调</param>
|
||||||
|
/// <returns>注册的附加属性</returns>
|
||||||
|
public static DependencyProperty Attach<TProperty>(string name, PropertyChangedCallback callback)
|
||||||
|
{
|
||||||
|
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new PropertyMetadata(callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/Snap.Hutao/Snap.Hutao/Core/Validation/Must.cs
Normal file
87
src/Snap.Hutao/Snap.Hutao/Core/Validation/Must.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core.Validation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 封装验证方法,简化微软验证
|
||||||
|
/// </summary>
|
||||||
|
public static class Must
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Throws an exception if the specified parameter's value is null.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the parameter.</typeparam>
|
||||||
|
/// <param name="value">The value of the argument.</param>
|
||||||
|
/// <param name="parameterName">The name of the parameter to include in any thrown exception.</param>
|
||||||
|
/// <returns>The value of the parameter.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is <c>null</c>.</exception>
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
|
||||||
|
public static T NotNull<T>([NotNull] T value, [CallerArgumentExpression("value")] string? parameterName = null)
|
||||||
|
where T : class // ensures value-types aren't passed to a null checking method
|
||||||
|
{
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(parameterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unconditionally throws an <see cref="NotSupportedException"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Nothing. This method always throws.</returns>
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
[DoesNotReturn]
|
||||||
|
public static Exception NeverHappen()
|
||||||
|
{
|
||||||
|
// Keep these two as separate lines of code, so the debugger can come in during the assert dialog
|
||||||
|
// that the exception's constructor displays, and the debugger can then be made to skip the throw
|
||||||
|
// in order to continue the investigation.
|
||||||
|
NotSupportedException exception = new("该行为不应发生,请联系开发者进一步确认");
|
||||||
|
bool proceed = true; // allows debuggers to skip the throw statement
|
||||||
|
if (proceed)
|
||||||
|
{
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#pragma warning disable CS8763
|
||||||
|
return new Exception();
|
||||||
|
#pragma warning restore CS8763
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unconditionally throws an <see cref="NotSupportedException"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type that the method should be typed to return (although it never returns anything).</typeparam>
|
||||||
|
/// <returns>Nothing. This method always throws.</returns>
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
[DoesNotReturn]
|
||||||
|
[return: MaybeNull]
|
||||||
|
public static T NeverHappen<T>()
|
||||||
|
{
|
||||||
|
// Keep these two as separate lines of code, so the debugger can come in during the assert dialog
|
||||||
|
// that the exception's constructor displays, and the debugger can then be made to skip the throw
|
||||||
|
// in order to continue the investigation.
|
||||||
|
NotSupportedException exception = new("该行为不应发生,请联系开发者进一步确认");
|
||||||
|
bool proceed = true; // allows debuggers to skip the throw statement
|
||||||
|
if (proceed)
|
||||||
|
{
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#pragma warning disable CS8763 // 不应返回标记为 [DoesNotReturn] 的方法。
|
||||||
|
return default;
|
||||||
|
#pragma warning restore CS8763 // 不应返回标记为 [DoesNotReturn] 的方法。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/Snap.Hutao/Snap.Hutao/Extension/ReflectionExtension.cs
Normal file
60
src/Snap.Hutao/Snap.Hutao/Extension/ReflectionExtension.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Extension;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射扩展
|
||||||
|
/// </summary>
|
||||||
|
internal static class ReflectionExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在指定的成员中尝试获取标记的特性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TAttribute">特性的类型</typeparam>
|
||||||
|
/// <param name="type">类型</param>
|
||||||
|
/// <param name="attribute">获取的特性</param>
|
||||||
|
/// <returns>是否获取成功</returns>
|
||||||
|
public static bool TryGetAttribute<TAttribute>(this Type type, [NotNullWhen(true)] out TAttribute? attribute)
|
||||||
|
where TAttribute : Attribute
|
||||||
|
{
|
||||||
|
attribute = type.GetCustomAttribute<TAttribute>();
|
||||||
|
return attribute != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测类型是否实现接口
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TInterface">被实现的类型</typeparam>
|
||||||
|
/// <param name="type">被检测的类型/param>
|
||||||
|
/// <returns>是否实现接口</returns>
|
||||||
|
[SuppressMessage("", "SA1615")]
|
||||||
|
public static bool Implement<TInterface>(this Type type)
|
||||||
|
{
|
||||||
|
return type.IsAssignableTo(typeof(TInterface));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查程序集是否标记了指定的特性
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TAttribute">特性类型</typeparam>
|
||||||
|
/// <param name="assembly">指定的程序集</param>
|
||||||
|
/// <returns>是否标记了指定的特性</returns>
|
||||||
|
public static bool HasAttribute<TAttribute>(this Assembly assembly)
|
||||||
|
where TAttribute : Attribute
|
||||||
|
{
|
||||||
|
return assembly.GetCustomAttribute<TAttribute>() is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 对程序集中的所有类型进行指定的操作
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assembly">指定的程序集</param>
|
||||||
|
/// <param name="action">进行的操作</param>
|
||||||
|
public static void ForEachType(this Assembly assembly, Action<Type> action)
|
||||||
|
{
|
||||||
|
foreach (Type type in assembly.GetTypes())
|
||||||
|
{
|
||||||
|
action.Invoke(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/Snap.Hutao/Snap.Hutao/Extension/TupleExtensions.cs
Normal file
25
src/Snap.Hutao/Snap.Hutao/Extension/TupleExtensions.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Extension;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 元组扩展
|
||||||
|
/// </summary>
|
||||||
|
public static class TupleExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将二项元组转化为一个单项的字典
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">键类型</typeparam>
|
||||||
|
/// <typeparam name="TValue">值类型</typeparam>
|
||||||
|
/// <param name="tuple">元组</param>
|
||||||
|
/// <returns>仅包含一个项的字典</returns>
|
||||||
|
public static IDictionary<TKey, TValue> AsDictionary<TKey, TValue>(this (TKey Key, TValue Value) tuple)
|
||||||
|
where TKey : notnull
|
||||||
|
{
|
||||||
|
return new Dictionary<TKey, TValue>(1) { { tuple.Key, tuple.Value } };
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/Snap.Hutao/Snap.Hutao/GlobalUsing.cs
Normal file
12
src/Snap.Hutao/Snap.Hutao/GlobalUsing.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
global using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
global using Microsoft;
|
||||||
|
global using Snap.Hutao.Core.DependencyInjection;
|
||||||
|
global using Snap.Hutao.Core.DependencyInjection.Annotation;
|
||||||
|
global using Snap.Hutao.Core.Validation;
|
||||||
|
global using System;
|
||||||
|
global using System.Diagnostics.CodeAnalysis;
|
||||||
|
global using System.Windows;
|
||||||
|
global using System.Windows.Input;
|
||||||
@@ -7,5 +7,18 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:view="using:Snap.Hutao.View"
|
xmlns:view="using:Snap.Hutao.View"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<view:MainView/>
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="28"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
x:Name="TitleBarGrid"
|
||||||
|
Background="Transparent"/>
|
||||||
|
|
||||||
|
<view:MainView
|
||||||
|
Grid.Row="1"/>
|
||||||
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace Snap.Hutao;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 主窗体
|
/// 主窗体
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Injection(InjectAs.Transient)]
|
||||||
public sealed partial class MainWindow : Window
|
public sealed partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -17,5 +18,6 @@ public sealed partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
ExtendsContentIntoTitleBar = true;
|
ExtendsContentIntoTitleBar = true;
|
||||||
|
SetTitleBar(TitleBarGrid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<Identity
|
<Identity
|
||||||
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
|
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
|
||||||
Publisher="CN=16861"
|
Publisher="CN=DGP Studio"
|
||||||
Version="1.0.0.0" />
|
Version="1.0.0.0" />
|
||||||
|
|
||||||
<Properties>
|
<Properties>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<Resources>
|
<Resources>
|
||||||
<Resource Language="x-generate"/>
|
<Resource Language="x-generate"/>
|
||||||
</Resources>
|
</Resources>
|
||||||
|
|
||||||
<Applications>
|
<Applications>
|
||||||
<Application Id="App"
|
<Application Id="App"
|
||||||
Executable="$targetnametoken$.exe"
|
Executable="$targetnametoken$.exe"
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Service.Abstraction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航服务
|
||||||
|
/// </summary>
|
||||||
|
public interface INavigationService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 管理的 <see cref="Frame"/>
|
||||||
|
/// </summary>
|
||||||
|
Frame? Frame { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指示是否曾导航过,用于启动时导航判断
|
||||||
|
/// </summary>
|
||||||
|
bool HasEverNavigated { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 管理的 <see cref="NavigationView"/>
|
||||||
|
/// </summary>
|
||||||
|
NavigationView? NavigationView { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 选中的 <see cref="NavigationViewItem"/>
|
||||||
|
/// </summary>
|
||||||
|
NavigationViewItem? Selected { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用指定的对象进行初始化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="navigationView">管理的 <see cref="NavigationView"/></param>
|
||||||
|
/// <param name="frame">管理的 <see cref="Frame"/></param>
|
||||||
|
void Initialize(NavigationView navigationView, Frame frame);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航到指定类型的页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pageType">指定的页面类型</param>
|
||||||
|
/// <param name="isSyncTabRequested">是否同步标签,当在代码中调用时应设为 true</param>
|
||||||
|
/// <param name="data">要传递的数据</param>
|
||||||
|
/// <returns>是否导航成功</returns>
|
||||||
|
bool Navigate(Type? pageType, bool isSyncTabRequested = false, object? data = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航到指定类型的页面
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">指定的页面类型</typeparam>
|
||||||
|
/// <param name="isSyncTabRequested">是否同步标签,当在代码中调用时应设为 true</param>
|
||||||
|
/// <param name="data">要传递的数据</param>
|
||||||
|
/// <returns>是否导航成功</returns>
|
||||||
|
bool Navigate<T>(bool isSyncTabRequested = false, object? data = null)
|
||||||
|
where T : Page;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 同步导航标签
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pageType">同步的页面类型</param>
|
||||||
|
/// <returns>是否同步成功</returns>
|
||||||
|
bool SyncTabWith(Type pageType);
|
||||||
|
}
|
||||||
157
src/Snap.Hutao/Snap.Hutao/Service/NavigationService.cs
Normal file
157
src/Snap.Hutao/Snap.Hutao/Service/NavigationService.cs
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Snap.Hutao.Core.Logging;
|
||||||
|
using Snap.Hutao.Extension;
|
||||||
|
using Snap.Hutao.Service.Abstraction;
|
||||||
|
using Snap.Hutao.View.Helper;
|
||||||
|
using Snap.Hutao.View.Page;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航服务
|
||||||
|
/// </summary>
|
||||||
|
[Injection(InjectAs.Transient, typeof(INavigationService))]
|
||||||
|
internal class NavigationService : INavigationService
|
||||||
|
{
|
||||||
|
private readonly ILogger<INavigationService> logger;
|
||||||
|
|
||||||
|
private NavigationView? navigationView;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造一个新的导航服务
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">日志器</param>
|
||||||
|
public NavigationService(ILogger<INavigationService> logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public Frame? Frame { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public NavigationView? NavigationView
|
||||||
|
{
|
||||||
|
get => navigationView;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// remove old listener
|
||||||
|
if (navigationView != null)
|
||||||
|
{
|
||||||
|
navigationView.ItemInvoked -= OnItemInvoked;
|
||||||
|
navigationView.BackRequested -= OnBackRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationView = Must.NotNull(value!, "NavigationView");
|
||||||
|
|
||||||
|
// add new listener
|
||||||
|
if (navigationView != null)
|
||||||
|
{
|
||||||
|
navigationView.ItemInvoked += OnItemInvoked;
|
||||||
|
navigationView.BackRequested += OnBackRequested;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public NavigationViewItem? Selected { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool HasEverNavigated { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool SyncTabWith(Type pageType)
|
||||||
|
{
|
||||||
|
if (NavigationView is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageType == typeof(SettingPage))
|
||||||
|
{
|
||||||
|
NavigationView.SelectedItem = NavigationView.SettingsItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NavigationViewItem? target = NavigationView.MenuItems
|
||||||
|
.OfType<NavigationViewItem>()
|
||||||
|
.SingleOrDefault(menuItem => NavHelper.GetNavigateTo(menuItem) == pageType);
|
||||||
|
NavigationView.SelectedItem = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
Selected = NavigationView.SelectedItem as NavigationViewItem;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Navigate(Type? pageType, bool isSyncTabRequested = false, object? data = null)
|
||||||
|
{
|
||||||
|
Type? currentType = Frame?.Content?.GetType();
|
||||||
|
if (pageType is null || (currentType == pageType))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = isSyncTabRequested && SyncTabWith(pageType);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = Frame?.Navigate(pageType, data) ?? false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(EventIds.NavigationFailed, ex, "导航到指定页面时发生了错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogInformation("Navigate to {pageType}:{result}", pageType, result ? "succeed" : "failed");
|
||||||
|
|
||||||
|
// 分析页面统计数据时不应加入启动时导航的首个页面
|
||||||
|
if (HasEverNavigated)
|
||||||
|
{
|
||||||
|
Analytics.TrackEvent("General", ("OpenUI", pageType.ToString()).AsDictionary());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首次导航失败时使属性持续保存为false
|
||||||
|
HasEverNavigated |= result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Navigate<T>(bool isSyncTabRequested = false, object? data = null)
|
||||||
|
where T : Page
|
||||||
|
{
|
||||||
|
return Navigate(typeof(T), isSyncTabRequested, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Initialize(NavigationView navigationView, Frame frame)
|
||||||
|
{
|
||||||
|
NavigationView = navigationView;
|
||||||
|
Frame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
||||||
|
{
|
||||||
|
Selected = NavigationView?.SelectedItem as NavigationViewItem;
|
||||||
|
Type? targetType = args.IsSettingsInvoked
|
||||||
|
? typeof(SettingPage)
|
||||||
|
: NavHelper.GetNavigateTo(Selected);
|
||||||
|
Navigate(targetType, false, NavHelper.GetExtraData(Selected));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args)
|
||||||
|
{
|
||||||
|
if (Frame != null && Frame.CanGoBack)
|
||||||
|
{
|
||||||
|
Frame.GoBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
|
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
<RootNamespace>Snap.Hutao</RootNamespace>
|
<RootNamespace>Snap.Hutao</RootNamespace>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
@@ -10,12 +10,24 @@
|
|||||||
<PublishProfile>win10-$(Platform).pubxml</PublishProfile>
|
<PublishProfile>win10-$(Platform).pubxml</PublishProfile>
|
||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
<ImplicitUsings>false</ImplicitUsings>
|
<ImplicitUsings>false</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||||
|
<NeutralLanguage>zh-CN</NeutralLanguage>
|
||||||
<DefaultLanguage>zh-CN</DefaultLanguage>
|
<DefaultLanguage>zh-CN</DefaultLanguage>
|
||||||
|
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||||
|
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||||
|
<PackageCertificateThumbprint>F8C2255969BEA4A681CED102771BF807856AEC02</PackageCertificateThumbprint>
|
||||||
|
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||||
|
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||||
|
<AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled>
|
||||||
|
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||||
|
<AppxBundle>Never</AppxBundle>
|
||||||
|
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="stylecop.json" />
|
<None Remove="stylecop.json" />
|
||||||
<None Remove="View\MainView.xaml" />
|
<None Remove="View\MainView.xaml" />
|
||||||
|
<None Remove="View\Page\SettingPage.xaml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="stylecop.json" />
|
<AdditionalFiles Include="stylecop.json" />
|
||||||
@@ -32,8 +44,18 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.0.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="7.1.2" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI" Version="7.1.2" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
||||||
|
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.5.1" />
|
||||||
|
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.0.3" />
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22000.197" />
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22000.197" />
|
||||||
|
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.8" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
@@ -51,12 +73,17 @@
|
|||||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Common\Snap.Core.Mvvm\Snap.Core.Mvvm.csproj" />
|
<Folder Include="Control\" />
|
||||||
|
<Folder Include="ViewModel\" />
|
||||||
|
<Folder Include="Model\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Service\Abstraction\" />
|
<ProjectReference Include="..\..\SettingsUI\SettingsUI.csproj" />
|
||||||
<Folder Include="ViewModel\" />
|
</ItemGroup>
|
||||||
<Folder Include="DataModel\" />
|
<ItemGroup>
|
||||||
|
<Page Update="View\Page\SettingPage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Update="View\MainView.xaml">
|
<Page Update="View\MainView.xaml">
|
||||||
|
|||||||
57
src/Snap.Hutao/Snap.Hutao/View/Helper/NavHelper.cs
Normal file
57
src/Snap.Hutao/Snap.Hutao/View/Helper/NavHelper.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Snap.Hutao.Core;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.View.Helper;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导航项帮助类
|
||||||
|
/// </summary>
|
||||||
|
public sealed class NavHelper
|
||||||
|
{
|
||||||
|
private static readonly DependencyProperty NavigateToProperty = Property<NavHelper>.Attach<Type>("NavigateTo");
|
||||||
|
private static readonly DependencyProperty ExtraDataProperty = Property<NavHelper>.Attach<object>("ExtraData");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取导航项的目标页面类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">待获取的导航项</param>
|
||||||
|
/// <returns>目标页面类型</returns>
|
||||||
|
public static Type? GetNavigateTo(NavigationViewItem? item)
|
||||||
|
{
|
||||||
|
return item?.GetValue(NavigateToProperty) as Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置导航项的目标页面类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">待设置的导航项</param>
|
||||||
|
/// <param name="value">新的目标页面类型</param>
|
||||||
|
public static void SetNavigateTo(NavigationViewItem item, Type value)
|
||||||
|
{
|
||||||
|
item.SetValue(NavigateToProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取导航项的目标页面的额外数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">待获取的导航项</param>
|
||||||
|
/// <returns>目标页面类型的额外数据</returns>
|
||||||
|
public static object? GetExtraData(NavigationViewItem? item)
|
||||||
|
{
|
||||||
|
return item?.GetValue(ExtraDataProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置导航项的目标页面类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">待设置的导航项</param>
|
||||||
|
/// <param name="value">新的目标页面类型</param>
|
||||||
|
public static void SetExtraData(NavigationViewItem item, object value)
|
||||||
|
{
|
||||||
|
item.SetValue(ExtraDataProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,10 +6,21 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<NavigationView OpenPaneLength="240" IsTitleBarAutoPaddingEnabled="False" Margin="0,32,0,0">
|
<NavigationView
|
||||||
|
x:Name="NavView"
|
||||||
|
OpenPaneLength="172"
|
||||||
|
Margin="0,0,0,0"
|
||||||
|
CompactModeThresholdWidth="360"
|
||||||
|
ExpandedModeThresholdWidth="720">
|
||||||
|
<Frame
|
||||||
|
x:Name="ContentFrame">
|
||||||
|
<Frame.ContentTransitions>
|
||||||
|
<NavigationThemeTransition>
|
||||||
|
<DrillInNavigationTransitionInfo/>
|
||||||
|
</NavigationThemeTransition>
|
||||||
|
</Frame.ContentTransitions>
|
||||||
|
</Frame>
|
||||||
</NavigationView>
|
</NavigationView>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
using Microsoft.UI.Xaml;
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
using Microsoft.UI.Xaml.Controls;
|
// Licensed under the MIT license.
|
||||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using Microsoft.UI.Xaml.Input;
|
|
||||||
using Microsoft.UI.Xaml.Media;
|
|
||||||
using Microsoft.UI.Xaml.Navigation;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using Windows.Foundation;
|
|
||||||
using Windows.Foundation.Collections;
|
|
||||||
|
|
||||||
// To learn more about WinUI, the WinUI project structure,
|
using Microsoft.UI.Xaml.Controls;
|
||||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
using Snap.Hutao.Service.Abstraction;
|
||||||
|
|
||||||
namespace Snap.Hutao.View;
|
namespace Snap.Hutao.View;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主视图
|
||||||
|
/// </summary>
|
||||||
public sealed partial class MainView : UserControl
|
public sealed partial class MainView : UserControl
|
||||||
{
|
{
|
||||||
|
private readonly INavigationService navigationService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造一个新的主视图
|
||||||
|
/// </summary>
|
||||||
public MainView()
|
public MainView()
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
|
|
||||||
|
navigationService = Ioc.Default.GetRequiredService<INavigationService>();
|
||||||
|
navigationService.Initialize(NavView, ContentFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml
Normal file
43
src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<Page
|
||||||
|
x:Class="Snap.Hutao.View.Page.SettingPage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:Snap.Hutao.View.Page"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:controls="using:SettingsUI.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
<Page.Resources>
|
||||||
|
<Style TargetType="Expander">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
</Style>
|
||||||
|
</Page.Resources>
|
||||||
|
<ScrollViewer>
|
||||||
|
<StackPanel
|
||||||
|
Margin="32,0,24,0">
|
||||||
|
|
||||||
|
<controls:SettingsGroup
|
||||||
|
Header="关于 胡桃">
|
||||||
|
<controls:SettingExpander>
|
||||||
|
<controls:SettingExpander.Header>
|
||||||
|
<controls:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="检查更新"
|
||||||
|
Description="根本没有检查更新选项">
|
||||||
|
|
||||||
|
</controls:Setting>
|
||||||
|
</controls:SettingExpander.Header>
|
||||||
|
<InfoBar
|
||||||
|
IsClosable="False"
|
||||||
|
Severity="Informational"
|
||||||
|
Message="都说了没有了"
|
||||||
|
IsOpen="True"
|
||||||
|
CornerRadius="0,0,4,4"/>
|
||||||
|
</controls:SettingExpander>
|
||||||
|
</controls:SettingsGroup>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Page>
|
||||||
18
src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs
Normal file
18
src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace Snap.Hutao.View.Page;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class SettingPage : Microsoft.UI.Xaml.Controls.Page
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构造新的设置页面
|
||||||
|
/// </summary>
|
||||||
|
public SettingPage()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user