@@ -160,10 +160,7 @@ public bool IsMaximized
160160 {
161161 _isMaximized = value ;
162162
163- if ( MaximizeButton != null )
164- {
165- VisualStateManager . GoToState ( MaximizeButton , value ? "Maximized" : "Restored" , false ) ;
166- }
163+ ApplyMaximizeGlyph ( ) ;
167164 }
168165 }
169166 }
@@ -212,6 +209,11 @@ public void SetCaptionButtonState(CaptionButtons button, bool pressed)
212209 GoToCaptionButtonState ( CloseButton , CaptionButtons . Close ) ;
213210 }
214211
212+ /// <summary>
213+ /// The window's own caption buttons dim while it is not the active one, the way the shell's
214+ /// do. Pushed in by the host: neither the buttons nor the presenter can see activation, and
215+ /// on Win32 the pointer is over the drag bar rather than over them.
216+ /// </summary>
215217 private void GoToCaptionButtonState ( Button button , CaptionButtons which )
216218 {
217219 if ( button == null )
@@ -220,10 +222,41 @@ private void GoToCaptionButtonState(Button button, CaptionButtons which)
220222 }
221223
222224 var state = _hotButton != which
223- ? "Normal"
225+ ? _isActive ? "Normal" : "Unfocused "
224226 : _hotPressed ? "Pressed" : "PointerOver" ;
225227
226- VisualStateManager . GoToState ( button , state , false ) ;
228+ // Transitions, so leaving a button fades the way the system's do rather than snapping.
229+ VisualStateManager . GoToState ( button , state , true ) ;
230+ }
231+
232+ private bool _isActive = true ;
233+ /// <summary>
234+ /// Whether the window is the active one. The system dims its caption glyphs when it is not,
235+ /// and nothing about a button's own pointer state says so - the host has to tell us.
236+ /// </summary>
237+ public bool IsActive
238+ {
239+ get => _isActive ;
240+ set
241+ {
242+ if ( _isActive != value )
243+ {
244+ _isActive = value ;
245+
246+ GoToCaptionButtonState ( MinimizeButton , CaptionButtons . Minimize ) ;
247+ GoToCaptionButtonState ( MaximizeButton , CaptionButtons . Maximize ) ;
248+ GoToCaptionButtonState ( CloseButton , CaptionButtons . Close ) ;
249+ }
250+ }
251+ }
252+
253+ private void ApplyMaximizeGlyph ( )
254+ {
255+ if ( MaximizeButton != null )
256+ {
257+ VisualStateManager . GoToState ( MaximizeButton ,
258+ _isMaximized ? "WindowStateMaximized" : "WindowStateNormal" , false ) ;
259+ }
227260 }
228261
229262 protected override void OnApplyTemplate ( )
@@ -253,10 +286,7 @@ protected override void OnApplyTemplate()
253286 }
254287
255288 // The window can already be maximized by the time the template arrives.
256- if ( MaximizeButton != null && _isMaximized )
257- {
258- VisualStateManager . GoToState ( MaximizeButton , "Maximized" , false ) ;
259- }
289+ ApplyMaximizeGlyph ( ) ;
260290
261291 ApplyCaptionButtons ( ) ;
262292
0 commit comments