Closed reduckted closed 3 years ago
This is amazing work. Thank you so much!!!
When I open RunnerWindowControl.xaml and MultiInstanceWindowControl.xaml I get this error message in the design which is failing to load.
The designer loads correctly again after setting UseVsTheme
to false like so:
toolkit:Themes.UseVsTheme="True"
ThemeWindowControl.xaml shows another error that may be related:
I was able to get the full stack trace of the error:
System.ArgumentNullException: Value cannot be null.
Parameter name: item
at System.Windows.ResourceDictionaryCollection.InsertItem(Int32 index, ResourceDictionary item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at Microsoft.VisualStudio.PlatformUI.ThemedDialogStyleLoader.MergeDefaultThemedDialogStyles(FrameworkElement element)
at Microsoft.VisualStudio.PlatformUI.ThemedDialogStyleLoader.OnUseDefaultThemedDialogStylesChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Microsoft.VisualStudio.PlatformUI.ThemedDialogStyleLoader.SetUseDefaultThemedDialogStyles(FrameworkElement element, Boolean value)
at Community.VisualStudio.Toolkit.Themes.UseVsThemePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
At a guess, I'd say that when the UseDefaultThemedDialogStyles
dependency property is set, the resource with the key VsResourceKeys.ThemedDialogDefaultStylesKey
couldn't be found, but the MergeDefaultThemedDialogStyles
doesn't check if it was found and just adds the null ResourceDictionary
to the collection, causing the exception.
As for not being able to load ThemeWindowDemo
, that seems to be caused by the use of WatermarkedTextBox
on that control. When I removed that control, the ThemeWindowDemo
control was able to be created in the designer.
I've cleaned up the
UseVsTheme
attached property, and also improved it in a few ways:First of all, I created a tool window and dialog window in the test project to demonstrate theming.
I've renamed it from
VsTheme.UseVsTheme
toThemes.UseVsTheme
, because I felt thatThemes
fitted better with other classes in this project (likeWindows
,Events
, and so on). Also moved it to a "Themes" folder. I'm happy to change it back if you prefer the old name. šThe "Get" and "Set" methods for the attached property weren't following standard practice. I've changed them to just set and get the value of the attached property, and moved all of the change handling to the "property change" event handler.
Instead of keeping track of themed elements and their original background property values in a static dictionary, the original background values are now stored in private attached properties. This should prevent memory leaks because the references to the controls are no longer kept in the dictionary.
TextBlock
s weren't being themed. This has been fixed by setting theForeground
property in the same way as theBackground
property. I wasn't sure exactly which resource to use, so I usedStartPageTextBodyBrushKey
. It seemed to be a good fit given the background was being set toStartPageTabBackgroundBrushKey
.Instead of loading resource dictionaries from internal assemblies, I've used the
ThemedDialogStyleLoader.UseDefaultThemedDialogStyles
andImageThemingUtilities.ThemeScrollBars
attached properties, which achieve the same thing.The custom styles for
TextBox
andComboBox
use the resource keys fromVsResourceKeys
instead of finding the style in the resource dictionary that was loaded from the internal assemblies.When the property is set to true, if the element hasn't been initialized, an event handler is added so that the custom resource dictionary is merged after the element is loaded. I haven't noticed a difference in behavior, but that's what the
ThemedDialogStyleLoader.UseDefaultThemedDialogStyles
property does, so I figured it was a good idea to do the same thing.Merging the custom resource dictionary is a lot simpler (and follows the same pattern that
ThemedDialogStyleLoader.UseDefaultThemedDialogStyles
does). AFrameworkElement
'sResources
property is never null, so the custom resource dictionary can just be added to theMergedDictionaries
property of the element's resources.The custom padding used for
TextBox
andComboBox
is also added to the custom resource dictionary using the new keyToolkitResourceKeys.InputPaddingKey
so that it can be used elsewhere if needed.I'm not sure about this one, but I've changed that custom padding from
(2, 3, 2, 3)
to(6, 8, 6, 8)
. The reason I did this is because theMicrosoft.VisualStudio.PlatformUI.WatermarkedTextBox
that's available in the SDK from (I think) 16.3 onwards uses that larger padding. It does look a bit too large, though. I've added theWatermarkedTextBox
to the demo tool window, so see what you think. I'm more than happy to change it back to the smaller padding.