@@ -135,6 +135,10 @@ public partial class Form : ContainerControl
135
135
private static readonly int s_propOpacity = PropertyStore . CreateKey ( ) ;
136
136
private static readonly int s_propTransparencyKey = PropertyStore . CreateKey ( ) ;
137
137
private static readonly int s_propFormCornerPreference = PropertyStore . CreateKey ( ) ;
138
+ private static readonly int s_propFormBorderColor = PropertyStore . CreateKey ( ) ;
139
+
140
+ private static readonly int s_propFormCaptionTextColor = PropertyStore . CreateKey ( ) ;
141
+ private static readonly int s_propFormCaptionBackColor = PropertyStore . CreateKey ( ) ;
138
142
139
143
// Form per instance members
140
144
// Note: Do not add anything to this list unless absolutely necessary.
@@ -2314,8 +2318,21 @@ protected override void SetVisibleCore(bool value)
2314
2318
}
2315
2319
2316
2320
/// <summary>
2317
- /// Sets or gets the rounding style of the corners using the <see cref="FormCornerPreference"/> enum.
2321
+ /// Sets or gets the rounding style of the Form's corners using the <see cref="FormCornerPreference"/> enum.
2318
2322
/// </summary>
2323
+ /// <remarks>
2324
+ /// <para>
2325
+ /// Note: Reading this property is only for tracking purposes. If the Form's corner preference is
2326
+ /// changed through other external means (Win32 calls), reading this property will not reflect
2327
+ /// those changes, as the Win32 API does not provide a mechanism to retrieve the current title
2328
+ /// bar color.
2329
+ /// </para>
2330
+ /// <para>
2331
+ /// The property only reflects the value that was previously set using this property. The
2332
+ /// <see cref="FormCornerPreferenceChanged"/> event is raised accordingly when the value is
2333
+ /// changed, which allows the property to be participating in binding scenarios.
2334
+ /// </para>
2335
+ /// </remarks>
2319
2336
[ DefaultValue ( FormCornerPreference . Default ) ]
2320
2337
[ SRCategory ( nameof ( SR . CatWindowStyle ) ) ]
2321
2338
[ SRDescription ( nameof ( SR . FormCornerPreferenceDescr ) ) ]
@@ -2341,7 +2358,14 @@ public FormCornerPreference FormCornerPreference
2341
2358
_ => throw new ArgumentOutOfRangeException ( nameof ( value ) )
2342
2359
} ;
2343
2360
2344
- Properties . AddOrRemoveValue ( s_propFormCornerPreference , value ) ;
2361
+ if ( value == FormCornerPreference . Default )
2362
+ {
2363
+ Properties . RemoveValue ( s_propFormCornerPreference ) ;
2364
+ }
2365
+ else
2366
+ {
2367
+ Properties . AddValue ( s_propFormCornerPreference , value ) ;
2368
+ }
2345
2369
2346
2370
if ( IsHandleCreated )
2347
2371
{
@@ -2356,6 +2380,9 @@ public FormCornerPreference FormCornerPreference
2356
2380
/// Raises the <see cref="FormCornerPreferenceChanged"/> event when the
2357
2381
/// <see cref="FormCornerPreference"/> property changes.
2358
2382
/// </summary>
2383
+ /// <param name="e">
2384
+ /// An <see cref="EventArgs"/> that contains the event data, in this case empty.
2385
+ /// </param>
2359
2386
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2360
2387
protected virtual void OnFormCornerPreferenceChanged ( EventArgs e )
2361
2388
{
@@ -2388,21 +2415,41 @@ private unsafe void SetFormCornerPreferenceInternal(FormCornerPreference cornerP
2388
2415
/// <summary>
2389
2416
/// Sets or gets the Form's border color.
2390
2417
/// </summary>
2418
+ /// <returns>
2419
+ /// The <see cref="Color"/> which has be previously set using this property or <see cref="Color.Empty"/>.
2420
+ /// Note that the underlying Win32 API does not provide a reliable mechanism to retrieve the current
2421
+ /// border color.
2422
+ /// </returns>
2423
+ /// <remarks>
2424
+ /// <para>
2425
+ /// Note: Reading this property is only for tracking purposes. If the Form's border color is
2426
+ /// changed through other external means (Win32 calls), reading this property will not reflect
2427
+ /// those changes, as the Win32 API does not provide a mechanism to retrieve the current title
2428
+ /// bar color.
2429
+ /// </para>
2430
+ /// <para>
2431
+ /// The property only reflects the value that was previously set using this property. The
2432
+ /// <see cref="FormBorderColorChanged"/> event is raised accordingly when the value is
2433
+ /// changed, which allows the property to be participating in binding scenarios.
2434
+ /// </para>
2435
+ /// </remarks>
2391
2436
[ SRCategory ( nameof ( SR . CatWindowStyle ) ) ]
2392
2437
[ SRDescription ( nameof ( SR . FormBorderColorDescr ) ) ]
2393
2438
[ Browsable ( false ) ]
2394
2439
[ DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
2395
2440
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2396
2441
public Color FormBorderColor
2397
2442
{
2398
- get => GetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_BORDER_COLOR ) ;
2443
+ get => Properties . GetValueOrDefault ( s_propFormBorderColor , Color . Empty ) ;
2399
2444
set
2400
2445
{
2401
2446
if ( value == FormBorderColor )
2402
2447
{
2403
2448
return ;
2404
2449
}
2405
2450
2451
+ Properties . AddValue ( s_propFormBorderColor , value ) ;
2452
+
2406
2453
if ( IsHandleCreated )
2407
2454
{
2408
2455
SetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_BORDER_COLOR , value ) ;
@@ -2415,6 +2462,9 @@ public Color FormBorderColor
2415
2462
/// <summary>
2416
2463
/// Raises the <see cref="FormBorderColorChanged"/> event when the <see cref="FormBorderColor"/> property changes.
2417
2464
/// </summary>
2465
+ /// <param name="e">
2466
+ /// An <see cref="EventArgs"/> that contains the event data, in this case empty.
2467
+ /// </param>
2418
2468
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2419
2469
protected virtual void OnFormBorderColorChanged ( EventArgs e )
2420
2470
{
@@ -2425,23 +2475,43 @@ protected virtual void OnFormBorderColorChanged(EventArgs e)
2425
2475
}
2426
2476
2427
2477
/// <summary>
2428
- /// Sets or gets the Form's title bar back color.
2478
+ /// Sets or gets the Form's title bar back color (caption back color) .
2429
2479
/// </summary>
2480
+ /// <returns>
2481
+ /// The <see cref="Color"/>, which has be previously set using this property or <see cref="Color.Empty"/>.
2482
+ /// Note that the underlying Win32 API does not provide a reliable mechanism to retrieve the current title
2483
+ /// bar color.
2484
+ /// </returns>
2485
+ /// <remarks>
2486
+ /// <para>
2487
+ /// Note: Reading this property is only for tracking purposes. If the window's title bar color is
2488
+ /// changed through other external means (Win32 calls), reading this property will not reflect
2489
+ /// those changes, as the Win32 API does not provide a mechanism to retrieve the current title
2490
+ /// bar color.
2491
+ /// </para>
2492
+ /// <para>
2493
+ /// The property only reflects the value that was previously set using this property. The
2494
+ /// <see cref="FormCaptionBackColorChanged"/> event is raised accordingly when the value is
2495
+ /// changed, which allows the property to be participating in binding scenarios.
2496
+ /// </para>
2497
+ /// </remarks>
2430
2498
[ SRCategory ( nameof ( SR . CatWindowStyle ) ) ]
2431
2499
[ SRDescription ( nameof ( SR . FormCaptionBackColorDescr ) ) ]
2432
2500
[ Browsable ( false ) ]
2433
2501
[ DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
2434
2502
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2435
2503
public Color FormCaptionBackColor
2436
2504
{
2437
- get => GetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_CAPTION_COLOR ) ;
2505
+ get => Properties . GetValueOrDefault ( s_propFormCaptionBackColor , Color . Empty ) ;
2438
2506
set
2439
2507
{
2440
2508
if ( value == FormCaptionBackColor )
2441
2509
{
2442
2510
return ;
2443
2511
}
2444
2512
2513
+ Properties . AddValue ( s_propFormCaptionBackColor , value ) ;
2514
+
2445
2515
if ( IsHandleCreated )
2446
2516
{
2447
2517
SetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_CAPTION_COLOR , value ) ;
@@ -2452,8 +2522,12 @@ public Color FormCaptionBackColor
2452
2522
}
2453
2523
2454
2524
/// <summary>
2455
- /// Raises the <see cref="FormCaptionBackColor"/> event when the <see cref="FormCaptionBackColor"/> property changes.
2525
+ /// Raises the <see cref="FormCaptionBackColorChanged"/> event when the <see cref="FormCaptionBackColor"/>
2526
+ /// property changes.
2456
2527
/// </summary>
2528
+ /// <param name="e">
2529
+ /// An <see cref="EventArgs"/> that contains the event data, in this case empty.
2530
+ /// </param>
2457
2531
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2458
2532
protected virtual void OnFormCaptionBackColorChanged ( EventArgs e )
2459
2533
{
@@ -2464,23 +2538,43 @@ protected virtual void OnFormCaptionBackColorChanged(EventArgs e)
2464
2538
}
2465
2539
2466
2540
/// <summary>
2467
- /// Sets or gets the Form's title bar back color.
2541
+ /// Sets or gets the Form's title bar text color (windows caption text color) .
2468
2542
/// </summary>
2543
+ /// <returns>
2544
+ /// The <see cref="Color"/>, which has be previously set using this property or <see cref="Color.Empty"/>.
2545
+ /// Note that the underlying Win32 API does not provide a reliable mechanism to retrieve the current title
2546
+ /// bar text color.
2547
+ /// </returns>
2548
+ /// <remarks>
2549
+ /// <para>
2550
+ /// Note: Reading this property is only for tracking purposes. If the Form's title bar's text color
2551
+ /// (window caption text) is changed through other external means (Win32 calls), reading this property
2552
+ /// will not reflect those changes, as the Win32 API does not provide a mechanism to retrieve the
2553
+ /// current title bar color.
2554
+ /// </para>
2555
+ /// <para>
2556
+ /// The property only reflects the value that was previously set using this property. The
2557
+ /// <see cref="FormCaptionTextColorChanged"/> event is raised accordingly when the value is
2558
+ /// changed, which allows the property to be participating in binding scenarios.
2559
+ /// </para>
2560
+ /// </remarks>
2469
2561
[ SRCategory ( nameof ( SR . CatWindowStyle ) ) ]
2470
2562
[ SRDescription ( nameof ( SR . FormCaptionTextColorDescr ) ) ]
2471
2563
[ Browsable ( false ) ]
2472
2564
[ DesignerSerializationVisibility ( DesignerSerializationVisibility . Hidden ) ]
2473
2565
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2474
2566
public Color FormCaptionTextColor
2475
2567
{
2476
- get => GetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_TEXT_COLOR ) ;
2568
+ get => Properties . GetValueOrDefault ( s_propFormCaptionTextColor , Color . Empty ) ;
2477
2569
set
2478
2570
{
2479
2571
if ( value == FormCaptionTextColor )
2480
2572
{
2481
2573
return ;
2482
2574
}
2483
2575
2576
+ Properties . AddValue ( s_propFormCaptionTextColor , value ) ;
2577
+
2484
2578
if ( IsHandleCreated )
2485
2579
{
2486
2580
SetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_TEXT_COLOR , value ) ;
@@ -2491,12 +2585,16 @@ public Color FormCaptionTextColor
2491
2585
}
2492
2586
2493
2587
/// <summary>
2494
- /// Raises the <see cref="FormCaptionTextColor"/> event when the <see cref="FormCaptionTextColor"/> property changes.
2588
+ /// Raises the <see cref="FormCaptionTextColorChanged"/> event when the
2589
+ /// <see cref="FormCaptionTextColor"/> property changes.
2495
2590
/// </summary>
2591
+ /// <param name="e">
2592
+ /// An <see cref="EventArgs"/> that contains the event data, in this case empty.
2593
+ /// </param>
2496
2594
[ Experimental ( DiagnosticIDs . ExperimentalDarkMode , UrlFormat = DiagnosticIDs . UrlFormat ) ]
2497
2595
protected virtual void OnFormCaptionTextColorChanged ( EventArgs e )
2498
2596
{
2499
- if ( Events [ s_formCaptionBackColorChanged ] is EventHandler eventHandler )
2597
+ if ( Events [ s_formCaptionTextColorChanged ] is EventHandler eventHandler )
2500
2598
{
2501
2599
eventHandler ( this , e ) ;
2502
2600
}
@@ -4211,6 +4309,29 @@ protected override void OnHandleCreated(EventArgs e)
4211
4309
{
4212
4310
_formStateEx [ s_formStateExUseMdiChildProc ] = ( IsMdiChild && Visible ) ? 1 : 0 ;
4213
4311
base . OnHandleCreated ( e ) ;
4312
+
4313
+ if ( Properties . TryGetValue ( s_propFormBorderColor , out Color ? formBorderColor ) )
4314
+ {
4315
+ SetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_BORDER_COLOR , formBorderColor . Value ) ;
4316
+ }
4317
+
4318
+ if ( Properties . TryGetValue ( s_propFormCaptionBackColor , out Color ? formCaptionBackColor ) )
4319
+ {
4320
+ SetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_CAPTION_COLOR , formCaptionBackColor . Value ) ;
4321
+ }
4322
+
4323
+ if ( Properties . TryGetValue ( s_propFormCaptionTextColor , out Color ? formCaptionTextColor ) )
4324
+ {
4325
+ SetFormAttributeColorInternal ( DWMWINDOWATTRIBUTE . DWMWA_TEXT_COLOR , formCaptionTextColor . Value ) ;
4326
+ }
4327
+
4328
+ #pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
4329
+ if ( Properties . TryGetValue ( s_propFormCornerPreference , out FormCornerPreference ? cornerPreference ) )
4330
+ {
4331
+ SetFormCornerPreferenceInternal ( cornerPreference . Value ) ;
4332
+ }
4333
+ #pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
4334
+
4214
4335
UpdateLayered ( ) ;
4215
4336
}
4216
4337
@@ -5814,7 +5935,7 @@ public DialogResult ShowDialog(IWin32Window? owner)
5814
5935
/// This method immediately returns, even if the form is large and takes a long time to be set up.
5815
5936
/// </para>
5816
5937
/// <para>
5817
- /// If the form is already displayed asynchronously by <see cref="Form. ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
5938
+ /// If the form is already displayed asynchronously by <see cref="ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
5818
5939
/// </para>
5819
5940
/// <para>
5820
5941
/// An <see cref="InvalidOperationException"/> will also occur if no <see cref="WindowsFormsSynchronizationContext"/> could be retrieved or installed.
@@ -5849,7 +5970,7 @@ public DialogResult ShowDialog(IWin32Window? owner)
5849
5970
/// This method immediately returns, even if the form is large and takes a long time to be set up.
5850
5971
/// </para>
5851
5972
/// <para>
5852
- /// If the form is already displayed asynchronously by <see cref="Form. ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
5973
+ /// If the form is already displayed asynchronously by <see cref="ShowAsync"/>, an <see cref="InvalidOperationException"/> will be thrown.
5853
5974
/// </para>
5854
5975
/// <para>
5855
5976
/// An <see cref="InvalidOperationException"/> will also occur if no <see cref="WindowsFormsSynchronizationContext"/> could be retrieved or installed.
0 commit comments