diff --git a/Wpf.Ui.sln b/Wpf.Ui.sln index bbfbec25f..043f85d80 100644 --- a/Wpf.Ui.sln +++ b/Wpf.Ui.sln @@ -59,6 +59,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wpf.Ui.Demo.Dialogs", "samp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.DependencyInjection", "src\Wpf.Ui.DependencyInjection\Wpf.Ui.DependencyInjection.csproj", "{9C8D6133-9417-43A1-B54F-725009569D71}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wpf.Ui.Demo.SetResources.Simple", "samples\Wpf.Ui.Demo.SetResources.Simple\Wpf.Ui.Demo.SetResources.Simple.csproj", "{3B424CF4-09F8-47D3-8420-53D7A1165B9C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -353,6 +355,22 @@ Global {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x64.Build.0 = Release|Any CPU {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x86.ActiveCfg = Release|Any CPU {9C8D6133-9417-43A1-B54F-725009569D71}.Release|x86.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|arm64.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|arm64.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x64.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x64.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x86.ActiveCfg = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Debug|x86.Build.0 = Debug|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|Any CPU.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|arm64.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|arm64.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x64.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x64.Build.0 = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x86.ActiveCfg = Release|Any CPU + {3B424CF4-09F8-47D3-8420-53D7A1165B9C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -364,6 +382,7 @@ Global {5138077E-670E-413D-94D1-0825B6D1201B} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} {E37CD05A-EBFC-429D-A550-BEE44119FA9E} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} {7F6C7E7A-A4B5-4D12-88EB-217CA59284F4} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} + {3B424CF4-09F8-47D3-8420-53D7A1165B9C} = {D7EA6A65-3CB5-4A59-934A-B8402C849107} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {234CB3F9-5ADC-433F-BDBD-CB8EA59EB518} diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/App.xaml b/samples/Wpf.Ui.Demo.SetResources.Simple/App.xaml new file mode 100644 index 000000000..9e62e915c --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/App.xaml @@ -0,0 +1,7 @@ + + diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/App.xaml.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/App.xaml.cs new file mode 100644 index 000000000..3f52b99ec --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/App.xaml.cs @@ -0,0 +1,30 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System.Windows; +using Wpf.Ui.Appearance; +using Wpf.Ui.Markup; + +namespace Wpf.Ui.Demo.SetResources.Simple; + +/// +/// Interaction logic for App.xaml +/// +public partial class App +{ + public static readonly ThemesDictionary ThemesDictionary = new(); + public static readonly ControlsDictionary ControlsDictionary = new(); + + public static void Apply(ApplicationTheme theme) + { + ThemesDictionary.Theme = theme; + } + + public static void ApplyTheme(FrameworkElement element) + { + element.Resources.MergedDictionaries.Add(ThemesDictionary); + element.Resources.MergedDictionaries.Add(ControlsDictionary); + } +} \ No newline at end of file diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/AssemblyInfo.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/AssemblyInfo.cs new file mode 100644 index 000000000..b8f7eb71b --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/AssemblyInfo.cs @@ -0,0 +1,11 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located (used if a resource is not found in the page, or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly // where the generic resource dictionary is located (used if a resource is not found in the page, app, or any theme specific resource dictionaries) +)] diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Assets/applicationIcon-1024.png b/samples/Wpf.Ui.Demo.SetResources.Simple/Assets/applicationIcon-1024.png new file mode 100644 index 000000000..b70c4ed59 Binary files /dev/null and b/samples/Wpf.Ui.Demo.SetResources.Simple/Assets/applicationIcon-1024.png differ diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Assets/applicationIcon-256.png b/samples/Wpf.Ui.Demo.SetResources.Simple/Assets/applicationIcon-256.png new file mode 100644 index 000000000..6b5cf5d5a Binary files /dev/null and b/samples/Wpf.Ui.Demo.SetResources.Simple/Assets/applicationIcon-256.png differ diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/MainWindow.xaml b/samples/Wpf.Ui.Demo.SetResources.Simple/MainWindow.xaml new file mode 100644 index 000000000..333a6b88c --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/MainWindow.xaml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/MainWindow.xaml.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/MainWindow.xaml.cs new file mode 100644 index 000000000..c1d52481d --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/MainWindow.xaml.cs @@ -0,0 +1,28 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using Wpf.Ui.Appearance; +using Wpf.Ui.Controls; +using Wpf.Ui.Demo.SetResources.Simple.Views.Pages; +using Wpf.Ui.Markup; + +namespace Wpf.Ui.Demo.SetResources.Simple; + +/// +/// Interaction logic for MainWindow.xaml +/// +public partial class MainWindow +{ + public MainWindow() + { + DataContext = this; + + App.ApplyTheme(this); + + InitializeComponent(); + + Loaded += (_, _) => RootNavigation.Navigate(typeof(DashboardPage)); + } +} diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Models/DataColor.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/Models/DataColor.cs new file mode 100644 index 000000000..71f8cf991 --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Models/DataColor.cs @@ -0,0 +1,13 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System.Windows.Media; + +namespace Wpf.Ui.Demo.SetResources.Simple.Models; + +public struct DataColor +{ + public Brush Color { get; set; } +} diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Models/DataGroup.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/Models/DataGroup.cs new file mode 100644 index 000000000..0d6fa98c7 --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Models/DataGroup.cs @@ -0,0 +1,20 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +namespace Wpf.Ui.Demo.SetResources.Simple.Models; + +public class DataGroup +{ + public DataGroup(bool selected, string name, string groupName) + { + Selected = selected; + Name = name; + GroupName = groupName; + } + + public bool Selected { get; set; } + public string Name { get; set; } + public string GroupName { get; set; } +} \ No newline at end of file diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DashboardPage.xaml b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DashboardPage.xaml new file mode 100644 index 000000000..fa8266ddd --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DashboardPage.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DashboardPage.xaml.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DashboardPage.xaml.cs new file mode 100644 index 000000000..a90592a35 --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DashboardPage.xaml.cs @@ -0,0 +1,34 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System.Windows; + +namespace Wpf.Ui.Demo.SetResources.Simple.Views.Pages; + +/// +/// Interaction logic for DashboardPage.xaml +/// +public partial class DashboardPage +{ + private int _counter = 0; + + public DashboardPage() + { + App.ApplyTheme(this); + + DataContext = this; + InitializeComponent(); + + CounterTextBlock.SetCurrentValue(System.Windows.Controls.TextBlock.TextProperty, _counter.ToString()); + } + + private void OnBaseButtonClick(object sender, RoutedEventArgs e) + { + CounterTextBlock.SetCurrentValue( + System.Windows.Controls.TextBlock.TextProperty, + (++_counter).ToString() + ); + } +} diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DataPage.xaml b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DataPage.xaml new file mode 100644 index 000000000..a4a665399 --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DataPage.xaml @@ -0,0 +1,40 @@ + + + + + + + + + + + + diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DataPage.xaml.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DataPage.xaml.cs new file mode 100644 index 000000000..1e35e475f --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/DataPage.xaml.cs @@ -0,0 +1,51 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System; +using System.Collections.ObjectModel; +using System.Windows.Media; +using Wpf.Ui.Demo.SetResources.Simple.Models; + +namespace Wpf.Ui.Demo.SetResources.Simple.Views.Pages; + +/// +/// Interaction logic for DataView.xaml +/// +public partial class DataPage +{ + public ObservableCollection ColorsCollection { get; private set; } = []; + + public DataPage() + { + App.ApplyTheme(this); + + InitializeData(); + InitializeComponent(); + + ColorsItemsControl.ItemsSource = ColorsCollection; + } + + private void InitializeData() + { + var random = new Random(); + + for (int i = 0; i < 8192; i++) + { + ColorsCollection.Add( + new DataColor + { + Color = new SolidColorBrush( + Color.FromArgb( + (byte)200, + (byte)random.Next(0, 250), + (byte)random.Next(0, 250), + (byte)random.Next(0, 250) + ) + ), + } + ); + } + } +} diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/ExpanderPage.xaml b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/ExpanderPage.xaml new file mode 100644 index 000000000..4bdad87dd --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/ExpanderPage.xaml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/ExpanderPage.xaml.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/ExpanderPage.xaml.cs new file mode 100644 index 000000000..1541200cd --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/ExpanderPage.xaml.cs @@ -0,0 +1,39 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Windows.Controls; +using System.Windows.Data; +using Wpf.Ui.Demo.SetResources.Simple.Models; + +namespace Wpf.Ui.Demo.SetResources.Simple.Views.Pages; + +public partial class ExpanderPage +{ + public ObservableCollection GroupCollection { get; private set; } = []; + + public ExpanderPage() + { + App.ApplyTheme(this); + + InitializeData(); + InitializeComponent(); + + ICollectionView collectionView = CollectionViewSource.GetDefaultView(GroupCollection); + collectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(DataGroup.GroupName))); + + Group.ItemsSource = collectionView; + } + + private void InitializeData() + { + GroupCollection.Add(new DataGroup(false, "Audi", "Auto")); + GroupCollection.Add(new DataGroup(false, "Samsung S24 Ultra", "Phone")); + GroupCollection.Add(new DataGroup(true, "Apple iPhone 16 Pro", "Phone")); + GroupCollection.Add(new DataGroup(true, "Bugatti", "Auto")); + GroupCollection.Add(new DataGroup(false, "Lamborghini", "Auto")); + } +} \ No newline at end of file diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/SettingsPage.xaml b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/SettingsPage.xaml new file mode 100644 index 000000000..28122a67c --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/SettingsPage.xaml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/SettingsPage.xaml.cs b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/SettingsPage.xaml.cs new file mode 100644 index 000000000..623f7de2c --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Views/Pages/SettingsPage.xaml.cs @@ -0,0 +1,49 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +using System.Windows; +using Wpf.Ui.Appearance; + +namespace Wpf.Ui.Demo.SetResources.Simple.Views.Pages; + +/// +/// Interaction logic for SettingsPage.xaml +/// +public partial class SettingsPage +{ + public SettingsPage() + { + App.ApplyTheme(this); + + InitializeComponent(); + + AppVersionTextBlock.Text = $"WPF UI - Simple Demo - {GetAssemblyVersion()}"; + + if (Appearance.ApplicationThemeManager.GetAppTheme() == ApplicationTheme.Dark) + { + DarkThemeRadioButton.IsChecked = true; + } + else + { + LightThemeRadioButton.IsChecked = true; + } + } + + private void OnLightThemeRadioButtonChecked(object sender, RoutedEventArgs e) + { + App.Apply(ApplicationTheme.Light); + } + + private void OnDarkThemeRadioButtonChecked(object sender, RoutedEventArgs e) + { + App.Apply(ApplicationTheme.Dark); + } + + private static string GetAssemblyVersion() + { + return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() + ?? string.Empty; + } +} diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/Wpf.Ui.Demo.SetResources.Simple.csproj b/samples/Wpf.Ui.Demo.SetResources.Simple/Wpf.Ui.Demo.SetResources.Simple.csproj new file mode 100644 index 000000000..b57a6eb5c --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/Wpf.Ui.Demo.SetResources.Simple.csproj @@ -0,0 +1,33 @@ + + + + WinExe + net9.0-windows10.0.26100.0 + 10.0.17763.0 + true + app.manifest + applicationIcon.ico + $(NoWarn);SA1601 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/app.manifest b/samples/Wpf.Ui.Demo.SetResources.Simple/app.manifest new file mode 100644 index 000000000..86e79a9cc --- /dev/null +++ b/samples/Wpf.Ui.Demo.SetResources.Simple/app.manifest @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PerMonitor + true/PM + true + + + + + + + + + + diff --git a/samples/Wpf.Ui.Demo.SetResources.Simple/applicationIcon.ico b/samples/Wpf.Ui.Demo.SetResources.Simple/applicationIcon.ico new file mode 100644 index 000000000..cc128fda3 Binary files /dev/null and b/samples/Wpf.Ui.Demo.SetResources.Simple/applicationIcon.ico differ diff --git a/src/Wpf.Ui/Animations/AnimationProperties.cs b/src/Wpf.Ui/Animations/AnimationProperties.cs new file mode 100644 index 000000000..50b9eb2f7 --- /dev/null +++ b/src/Wpf.Ui/Animations/AnimationProperties.cs @@ -0,0 +1,27 @@ +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. +// Copyright (C) Leszek Pomianowski and WPF UI Contributors. +// All Rights Reserved. + +namespace Wpf.Ui.Animations; + +internal static class AnimationProperties +{ + public static readonly DependencyProperty AnimationTagValueProperty = DependencyProperty.RegisterAttached( + "AnimationTagValue", + typeof(double), + typeof(AnimationProperties), + new FrameworkPropertyMetadata( + 0.0, + FrameworkPropertyMetadataOptions.Inherits)); + + public static double GetAnimationTagValue(DependencyObject dp) + { + return (double)dp.GetValue(AnimationTagValueProperty); + } + + public static void SetAnimationTagValue(DependencyObject dp, double value) + { + dp.SetValue(AnimationTagValueProperty, value); + } +} \ No newline at end of file diff --git a/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml b/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml index 25d1836db..96a64b6fe 100644 --- a/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml +++ b/src/Wpf.Ui/Controls/CardExpander/CardExpander.xaml @@ -13,7 +13,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:Wpf.Ui.Controls" xmlns:converters="clr-namespace:Wpf.Ui.Converters" - xmlns:system="clr-namespace:System;assembly=System.Runtime"> + xmlns:system="clr-namespace:System;assembly=System.Runtime" + xmlns:animations="clr-namespace:Wpf.Ui.Animations"> 14,16,14,16 1 @@ -178,15 +179,12 @@ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" /> - - 0.0 - - + @@ -204,7 +202,7 @@ - + - + + xmlns:system="clr-namespace:System;assembly=System.Runtime" + xmlns:animations="clr-namespace:Wpf.Ui.Animations"> 11,11,11,11 1 @@ -149,15 +150,12 @@ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" /> - - 0.0 - - + @@ -175,7 +173,7 @@ - + - +