private async Task UpdateTitleBarControllerListAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); Window[] windows = new Window[Application.Current.Windows.Count]; Application.Current.Windows.CopyTo(windows, 0); // Destroy old ones. windowTitleBarController = windowTitleBarController.Where(x => windows.Contains(x.Key)) .ToDictionary(x => x.Key, x => x.Value); // Look for new ones to add. foreach (Window window in windows) { if (windowTitleBarController.ContainsKey(window)) { continue; } var newController = TitleBarColorController.CreateFromWindow(window); if (newController != null) { windowTitleBarController.Add(window, newController); // Check if we already saved something for this solution. // Do this in here since we call UpdateTitleBarControllerList fairly regularly and in the most cases won't have any new controllers. System.Drawing.Color color; if (Settings.GetSolutionColorSetting(VSUtils.GetCurrentSolutionPath(), out color)) { newController.SetTitleBarColor(color); } } } }
/// <summary> /// Uses knowledge of the VS window structure to retrieve pointers to the titlebar and its text element. /// </summary> static public TitleBarColorController CreateFromWindow(Window window) { TitleBarColorController newController = new TitleBarColorController(); try { // Apply knowledge of basic Visual Studio 2015/2017/2019 window structure. if (window == Application.Current.MainWindow) { var windowContentPresenter = VisualTreeHelper.GetChild(window, 0); var rootGrid = VisualTreeHelper.GetChild(windowContentPresenter, 0); newController.titleBarContainer = VisualTreeHelper.GetChild(rootGrid, 0); // Note that this part doesn't work for the VS2019 main windows as there is simply no title text like this. // However docked-out code windows are just like in previous versions. var dockPanel = VisualTreeHelper.GetChild(newController.titleBarContainer, 0); newController.titleBarTextBox = VisualTreeHelper.GetChild(dockPanel, 3) as TextBlock; } else { var windowContentPresenter = VisualTreeHelper.GetChild(window, 0); var rootGrid = VisualTreeHelper.GetChild(windowContentPresenter, 0); var rootDockPanel = VisualTreeHelper.GetChild(rootGrid, 0); var titleBarContainer = VisualTreeHelper.GetChild(rootDockPanel, 0); var titleBar = VisualTreeHelper.GetChild(titleBarContainer, 0); var border = VisualTreeHelper.GetChild(titleBar, 0); var contentPresenter = VisualTreeHelper.GetChild(border, 0); var grid = VisualTreeHelper.GetChild(contentPresenter, 0); newController.titleBarContainer = grid; newController.titleBarTextBox = VisualTreeHelper.GetChild(grid, 1) as TextBlock; } if (newController.titleBarContainer != null) { System.Reflection.PropertyInfo propertyInfo = newController.titleBarContainer.GetType().GetProperty(ColorPropertyName); newController.defaultBackgroundValue = propertyInfo.GetValue(newController.titleBarContainer); } if (newController.titleBarTextBox != null) { newController.defaultTextForeground = newController.titleBarTextBox.Foreground; } } catch { return(null); } if (newController.titleBarContainer == null) { return(null); } return(newController); }
/// <summary> /// Uses knowledge of the VS window structure to retrieve pointers to the titlebar and its text element. /// </summary> static public TitleBarColorController CreateFromWindow(Window window) { TitleBarColorController newController = new TitleBarColorController(); try { // Apply knowledge of basic Visual Studio 2015/2017 window structure. if (window == Application.Current.MainWindow) { var windowContentPresenter = VisualTreeHelper.GetChild(window, 0); var rootGrid = VisualTreeHelper.GetChild(windowContentPresenter, 0); newController.titleBarContainer = VisualTreeHelper.GetChild(rootGrid, 0); var dockPanel = VisualTreeHelper.GetChild(newController.titleBarContainer, 0); newController.titleBarTextBox = VisualTreeHelper.GetChild(dockPanel, 3) as TextBlock; } else { var windowContentPresenter = VisualTreeHelper.GetChild(window, 0); var rootGrid = VisualTreeHelper.GetChild(windowContentPresenter, 0); var rootDockPanel = VisualTreeHelper.GetChild(rootGrid, 0); var titleBarContainer = VisualTreeHelper.GetChild(rootDockPanel, 0); var titleBar = VisualTreeHelper.GetChild(titleBarContainer, 0); var border = VisualTreeHelper.GetChild(titleBar, 0); var contentPresenter = VisualTreeHelper.GetChild(border, 0); var grid = VisualTreeHelper.GetChild(contentPresenter, 0); newController.titleBarContainer = grid; newController.titleBarTextBox = VisualTreeHelper.GetChild(grid, 1) as TextBlock; } if (newController.titleBarContainer != null) { System.Reflection.PropertyInfo propertyInfo = newController.titleBarContainer.GetType().GetProperty(ColorPropertyName); newController.defaultBackgroundValue = propertyInfo.GetValue(newController.titleBarContainer); } if (newController.titleBarTextBox != null) { newController.defaultTextForeground = newController.titleBarTextBox.Foreground; } } catch { return(null); } if (newController.titleBarContainer == null || newController.titleBarTextBox == null) { return(null); } return(newController); }
/// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> protected override void Initialize() { TitleBarColorControl = new TitleBarColorController(); PickColorCommand.Initialize(this); ResetColorCommand.Initialize(this); solutionEvents = VSUtils.GetDTE().Events.SolutionEvents; solutionEvents.Opened += SolutionOpened; base.Initialize(); }