From 2489765a64eeb70ff41246b3d5d5cee4a37315d8 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Wed, 11 Dec 2024 14:32:48 -0800 Subject: [PATCH] Wpf: Isolate resource dictionaries by specifying Version and PublicKey --- .editorconfig | 80 ++++++++++++++++++- .gitignore | 1 + .../AssemblyAbsoluteResourceDictionary.cs | 45 +++++++++++ src/Eto.Wpf/Forms/ApplicationHandler.cs | 6 +- src/Eto.Wpf/themes/controls/DataGrid.xaml | 4 +- src/Eto.Wpf/themes/controls/ToggleButton.xaml | 4 +- src/Eto.Wpf/themes/controls/Window.xaml | 4 +- .../themes/controls/XceedColorDialog.xaml | 4 +- src/Eto.Wpf/themes/generic.xaml | 12 +-- 9 files changed, 136 insertions(+), 24 deletions(-) mode change 100644 => 100755 .editorconfig create mode 100755 src/Eto.Wpf/AssemblyAbsoluteResourceDictionary.cs diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 index 1c69d67698..2d22735b84 --- a/.editorconfig +++ b/.editorconfig @@ -5,11 +5,26 @@ root = true # use tabs by default for everything [*.cs] -indent_style = tab -indent_size = 4 -charset=utf-8 csharp_new_line_before_open_brace = all csharp_indent_braces=false +csharp_indent_labels = no_change +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_space_around_binary_operators = before_and_after [*.{csproj,vbproj,fsproj,proj,targets,props}] indent_style = space @@ -19,3 +34,62 @@ tab_size = 2 [*.yml] intent_style = space indent_size = 2 + +[*.{cs,vb}] +# Indentation style/size +charset=utf-8 +indent_style = tab +tab_width = 4 +indent_size = 4 + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent diff --git a/.gitignore b/.gitignore index ed5eb44e49..e2b9d49bbf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ packages/ .store .DS_Store *.proj.Backup.tmp +._.* diff --git a/src/Eto.Wpf/AssemblyAbsoluteResourceDictionary.cs b/src/Eto.Wpf/AssemblyAbsoluteResourceDictionary.cs new file mode 100755 index 0000000000..ec9d372c9a --- /dev/null +++ b/src/Eto.Wpf/AssemblyAbsoluteResourceDictionary.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Eto.Wpf +{ + public class AssemblyAbsoluteResourceDictionary : sw.ResourceDictionary, ISupportInitialize + { + public string AssemblyName { get; set; } + + public string Path { get; set; } + + internal static Uri GetAbsolutePackUri(string path, string assemblyName = null) + { + // Support having multiple copies of Eto running, potentially with different version and/or public key + var assembly = assemblyName != null ? Assembly.Load(assemblyName) : typeof(AssemblyAbsoluteResourceDictionary).Assembly; + var name = assembly.GetName(); + + var version = "v" + name.Version.ToString() + ";"; + + var publicKey = name.GetPublicKey(); + var publicKeyString = publicKey?.Length > 0 ? BitConverter.ToString(publicKey).Replace("-", "") + ";" : null; + + return new Uri($"pack://application:,,,/{name.Name};{version}{publicKeyString}component/{path}", UriKind.Absolute); + } + + void ISupportInitialize.EndInit() + { + SetupSource(); + + base.EndInit(); + } + + private void SetupSource() + { + if (Source != null) + return; + if (string.IsNullOrEmpty(Path)) + throw new InvalidOperationException("No Path was specified"); + + Source = GetAbsolutePackUri(Path, AssemblyName); + } + } +} \ No newline at end of file diff --git a/src/Eto.Wpf/Forms/ApplicationHandler.cs b/src/Eto.Wpf/Forms/ApplicationHandler.cs index d8dce0d128..6686aed04c 100755 --- a/src/Eto.Wpf/Forms/ApplicationHandler.cs +++ b/src/Eto.Wpf/Forms/ApplicationHandler.cs @@ -67,8 +67,8 @@ void ApplyThemes() throw new InvalidOperationException("Could not load Xceed.Wpf.Toolkit"); // Add themes to our controls - var assemblyName = typeof(ApplicationHandler).Assembly.GetName().Name; - Control.Resources.MergedDictionaries.Add(new sw.ResourceDictionary { Source = new Uri($"pack://application:,,,/{assemblyName};component/themes/generic.xaml", UriKind.RelativeOrAbsolute) }); + var uri = AssemblyAbsoluteResourceDictionary.GetAbsolutePackUri("themes/generic.xaml"); + Control.Resources.MergedDictionaries.Add(new sw.ResourceDictionary { Source = uri }); } protected override void Initialize() @@ -169,7 +169,7 @@ protected virtual swm.Imaging.BitmapSource GenerateBadge(float scale, string lab { var size = Size.Round(new SizeF(14, 14) * scale); var bmp = new Bitmap(size, PixelFormat.Format32bppRgba); - + using (var graphics = new Graphics(bmp)) { var font = SystemFonts.Bold(6 * scale); diff --git a/src/Eto.Wpf/themes/controls/DataGrid.xaml b/src/Eto.Wpf/themes/controls/DataGrid.xaml index 3bca284344..638e9e361e 100755 --- a/src/Eto.Wpf/themes/controls/DataGrid.xaml +++ b/src/Eto.Wpf/themes/controls/DataGrid.xaml @@ -3,9 +3,7 @@ xmlns:r="clr-namespace:Eto.Wpf.CustomControls.TreeGridView" xmlns:efc="clr-namespace:Eto.Wpf.Forms.Controls" xmlns:e="clr-namespace:Eto.Wpf" - xmlns:s="clr-namespace:System;assembly=mscorlib" - xmlns:themes="clr-namespace:Xceed.Wpf.Toolkit.Themes;assembly=Xceed.Wpf.Toolkit" - xmlns:local="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"> + xmlns:s="clr-namespace:System;assembly=mscorlib">