Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unimplemented types for deprecated UI controls #3783

Open
msneijders opened this issue Aug 26, 2020 · 23 comments · May be fixed by #10913
Open

Add unimplemented types for deprecated UI controls #3783

msneijders opened this issue Aug 26, 2020 · 23 comments · May be fixed by #10913
Assignees
Labels
api-approved (4) API was approved in API review, it can be implemented blocking-migration An issue that is preventing the developer from migrating from .NET Framework or earlier .NET 🚧 work in progress Work that is current in progress
Milestone

Comments

@msneijders
Copy link

msneijders commented Aug 26, 2020

Is your feature request related to a problem? Please describe.

I am migrating a large Winforms .NET Framework 4.7.1 solution to .NET 5.0 (preview 8). My biggest pain are the deprecated UI Controls like ContextMenu and related types like 'MenuMerge'. Not because of my own code, I don't use them anymore. But we use quite some 3rd party libraries who still have references to these deprecated types. Libraries that are not so much in development anymore.

For example a library supports both ContextMenu and ContextMenuStrip. I don't use ContextMenu, so this is always a null reference, but because the type ContextMenu cannot be loaded from System.Windows.Forms.dll using .NET5 all these 3rd party libraries are broken in runtime.

Describe the solution you'd like and alternatives you've considered

Re-add the previously removed types as "empty" placeholder types that provide binary compatibility, just so old libraries can load these types in runtime, then my solution conversion to .NET5 would be so much easier.
An alternative would be to provide the obsolete types with empty implementations in a new assembly and enable type forwarding to that assembly. That would allow 3rd parties to provide custom implementations if needed in an assembly with a higher version number. However, that wouldn't work for the obsolete properties on the existing types (Control.ContextMenu) and we hadn't received request for that in 5 releases of .NET.

History
WinForms had documented some APIs as obsolete in NETFX 2.0, we shipped them in .NET3.0, then removed them completely in .NET3.1 - Windows Forms breaking changes - .NET | Microsoft Learn.
Previous request to restore these types - #5368

API proposal

Add the following types to System.Windows.Forms assembly.

'System.Windows.Forms.ContextMenu'
'System.Windows.Forms.DataGrid'
'System.Windows.Forms.DataGrid.HitTestInfo'
'System.Windows.Forms.DataGrid.HitTestType'
'System.Windows.Forms.DataGridBoolColumn'
'System.Windows.Forms.DataGridCell'
'System.Windows.Forms.DataGridColumnStyle'
'System.Windows.Forms.DataGridColumnStyle.CompModSwitches'
'System.Windows.Forms.DataGridColumnStyle.DataGridColumnHeaderAccessibleObject'
'System.Windows.Forms.DataGridLineStyle'
'System.Windows.Forms.DataGridParentRowsLabelStyle'
'System.Windows.Forms.DataGridPreferredColumnWidthTypeConverter'
'System.Windows.Forms.DataGridTableStyle'
'System.Windows.Forms.DataGridTextBox'
'System.Windows.Forms.DataGridTextBoxColumn'
'System.Windows.Forms.GridColumnStylesCollection'
'System.Windows.Forms.GridTablesFactory'
'System.Windows.Forms.GridTableStylesCollection'
'System.Windows.Forms.IDataGridEditingService'
'System.Windows.Forms.MainMenu'
'System.Windows.Forms.Menu'
'System.Windows.Forms.Menu.MenuItemCollection'
'System.Windows.Forms.MenuItem'
'System.Windows.Forms.MenuMerge'
'System.Windows.Forms.StatusBar'
'System.Windows.Forms.StatusBarDrawItemEventArgs'
'System.Windows.Forms.StatusBarDrawItemEventHandler'
'System.Windows.Forms.StatusBarPanel'
'System.Windows.Forms.StatusBarPanelAutoSize'
'System.Windows.Forms.StatusBarPanelBorderStyle'
'System.Windows.Forms.StatusBarPanelClickEventArgs'
'System.Windows.Forms.StatusBarPanelClickEventHandler'
'System.Windows.Forms.StatusBarPanelStyle'
'System.Windows.Forms.ToolBar'
'System.Windows.Forms.ToolBarAppearance'
'System.Windows.Forms.ToolBarButton'
'System.Windows.Forms.ToolBarButtonClickEventArgs'
'System.Windows.Forms.ToolBarButtonClickEventHandler'
'System.Windows.Forms.ToolBar.ToolBarButtonCollection'
'System.Windows.Forms.ToolBarButtonStyle'
'System.Windows.Forms.ToolBarTextAlign'

This is the list of all removed public or protected types generated by the App Compat tool when matching .NET Framework 4.8.1 to the NET10.0 version.

Additionally, re-add the following methods that were using the removed types.

public partial class Form : ContainerControl
{
     [Obsolete("MainMenu is not supported. Use MenuStrip instead.", false, DiagnosticId = "WFDEV007", UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
     [System.ComponentModel.Browsable(false)]
     [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     public MainMenu Menu { get { throw null; } set { } }

     [Obsolete("MainMenu is not supported. Use MenuStrip instead.", false, DiagnosticId = "WFDEV007", UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
     [System.ComponentModel.Browsable(false)]
     [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     public MainMenu MergedMenu { get { throw null; } }
}

public partial class Control : System.ComponentModel.Component, IDropTarget, System.ComponentModel.ISynchronizeInvoke, IWin32Window, System.ComponentModel.IComponent, IDisposable, IBindableComponent
{
     [Obsolete("ContextMenu is not supported. Use ContextMenuStrip instead.", false, DiagnosticId = "WFDEV005", UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
     [System.ComponentModel.Browsable(false)]
     [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     public virtual ContextMenu ContextMenu { get { throw null; } set { } }

     [Obsolete("ContextMenu is not supported. Use ContextMenuStrip instead.", false, DiagnosticId = "WFDEV005", UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
     [System.ComponentModel.Browsable(false)]
     [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     public event EventHandler ContextMenuChanged { add { } remove { } }
	
     [Obsolete("ContextMenu is not supported. Use ContextMenuStrip instead.", false, DiagnosticId = "WFDEV005", UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
     [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     protected virtual void OnContextMenuChanged(EventArgs e) { }
}
  • None of the re-added types can be constructed, all constructors throw new PlatformNotSupportedException(), default constructors are avoided by introducing private constructors if needed.
  • All attributes that have been present on the .NET Framework types, are preserved, as they are accessible by code.
  • All re-introduced types are decorated with [EditorBrowsable(EditorBrowsableState.Never)] attribute that hides them from the intellisense. Type names can be typed in by the developer and then intellisense would show the same members as it did for .NET Framework projects.
  • All re-introduced types are decorated with the ObsoleteAttribute that results in a compile time warning. Types related to the same feature share a single deprecation warning Id.
  • All re-introduced types are decorated with [Browsable(false)] attribute to not show custom control properties of these types in the property browser.
Example
public partial class UserControl1 : UserControl
{
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public ContextMenu MyMenu
    {
        get; set;
    }
}

image

[Obsolete(
    "ContextMenu and its related types has been deprecated. Use ContextMenuStrip instead.",
    error: false,
    DiagnosticId = WFDEV###,
    UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
public class ContextMenu : Menu
{
    public ContextMenu() : base(items: null) => throw new PlatformNotSupportedException();
  • All other attributes are removed from the type members because they are not accessible. Most of these attributes were consumed by the designer, and these types can't be instantiated on the designer surface, and thus are not visible to Property Browser or design time serialization.
  • Members inherited from the base classes (Control for example) are not re-introduced even if they had been overridden in the past because they are not required for binary compatibility. An exception is properties or events that were decorated with
    [EditorBrowsable(EditorBrowsableState.Never)] in .NET Framework, as we don't want to show in intellisense members that have not been shown in the past.
  • Members that are re-added to the existing types (Form and Control) are returning a default or doing nothing.
  • Public or protected methods or properties on the restored types throw a PlatformNotSupportedException for consistency.
  • Public or protected fields return the default value.
  • nullability is disabled for all re-added classes, structs and delegates for compatibility with the .NET Framework.

Use Case

.NET applications can reference .NET Framework 3rd party libraries that use these types. Code will JIT and if the unsupported code is executed, it will throw an exception that can be caught instead of JIT throwing a missing member exception. For example:

if (control.ContextMenu is not null)
{
    control.ShowContextMenu();
} 
else
{
    // show a ContextMenuStrip
}
try
{
    LegacyControl.ShowContextMenu();
}
catch (PlatformNotSupportedException)
{
    // create a new ContextMenuStrip
}

To review

Compare the .NET Framework API in these classes - netfx.txt
To the .NET10 API surface generated by the same App Compat tool - review.txt

@msneijders msneijders added the api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation label Aug 26, 2020
@weltkante
Copy link
Contributor

weltkante commented Aug 27, 2020

I don't think this will work, I'm not 100% certain but I think loading types is lazy, so it already will only load them at the point they are used. However if they are used then it typically will be in the form/control constructor (in the generated designer code part), so throwing an exception will mean you have that exception being thrown in your third party form/control constructor. That probably is not helpful and just changes the error you are getting?

Libraries that are not so much in development anymore.

I suspect if these are WinForms based libraries you'll have a hard time to get this working properly in .NET Core, there are subtile changes like the default font being different which mean that it often needs code adjustments to work well on .NET Core.

It would have been nice to be able to just run Desktop Framework WinForms code on .NET Core but the decision was made against that and I don't think it can be changed at this point.

@msneijders
Copy link
Author

In general you are right and this will not work -- but all my 3rd party libraries are using the "new" controls that have replaced the deprecated ones -- it is just that they kept supporting the deprecated ones with code like "if (this.ContextMenuStrip != null) { ..use new control...} else if (this.ContextMenu != null) { ..keep it backwards compatible...}. Now if ContextMenu just worked and returned null as I do not use it, it would have worked in runtime -- now it gives "cannot find/load type ContextMenu.

Making it hard to upgrade existing winforms applications to .NET5 is a mistake in my opinion. (it all worked nicely in .NET Core 3.0, why change that?)

@weltkante
Copy link
Contributor

weltkante commented Aug 27, 2020

these controls already were removed in .NET Core 3.1 (the LTS version of 3.0 - .NET Core 3.0 is already out of support)

@msneijders
Copy link
Author

Exactly, that is why I cannot use .NET Core 3.0, not shipping something that is out of support to my customers.

@teo-tsirpanis
Copy link
Contributor

teo-tsirpanis commented Aug 27, 2020

@msneijders have you tried creating dummy classes for these deprecated types in your assembly, and type-forwarding them to the Windows Forms assembly?

@msneijders
Copy link
Author

@teo-tsirpanis I did not try this yet, but I will soon, thank you for this suggestion.

@JeremyKuhne JeremyKuhne added this to the Future milestone Aug 27, 2020
@msneijders
Copy link
Author

Type-forwarding does not seem like a workaround -- I think forwarding needs to be done from the System.Windows.Forms assembly.

@teo-tsirpanis
Copy link
Contributor

Hmm, doesn't it work the other way around? There's an attribute named TypeForwardedFrom which is applied to the declared type, in contrast with the TypeForwardedToAttribute which is applied to the receiving assembly.

It is written like this: [TypeForwardedFrom("System.Windows.Forms")].

@weltkante

This comment has been minimized.

@teo-tsirpanis
Copy link
Contributor

@msneijders said he doesn't himself use these legacy controls in application code. He uses an old control library wich supports both the legacy and the new controls, but the legacy control code path will never be executed.

We don't care about the compiler recognizing them. All we want is a runtime trick to not crash the loader because of a couple of classes were not found.

@weltkante

This comment has been minimized.

@JensNordenbro
Copy link

We also experienced this. Added dotnet/runtime#41088 , but ...
...basically we have accepted that moving to net5 means replacing some 3rd party altogether.

It is frustrating however that net core 3.0 had the types ...

@merriemcgaw merriemcgaw added the blocking-migration An issue that is preventing the developer from migrating from .NET Framework or earlier .NET label Jan 24, 2024
@merriemcgaw merriemcgaw modified the milestones: Future, .NET 9.0 Jan 24, 2024
@merriemcgaw
Copy link
Member

merriemcgaw commented Jan 24, 2024

@LeafShi1 let's get this on your team's radar, so that we can help customers do their migrations.
@Tanya-Solyanik FYI, per discussion with @JeremyKuhne

@Tanya-Solyanik Tanya-Solyanik self-assigned this Jan 31, 2024
@Tanya-Solyanik
Copy link
Member

@LeafShi1 @Epica3055 @SimonZhao888 @ricardobossan, here are the steps to start with -

  1. generate public API surface for NETFX 481 System.Windows.Forms.dd and for NET9 SystemWindows.Froms.dll and find public or protected APIs that we had removed, not only the classes but also class members. We have a list of removed controls here - https://learn.microsoft.com/dotnet/core/compatibility/winforms#removed-controls but it might be incomplete.
  2. create a repro application based on the description in this issue, a .NET9 exe that references a NETFX481 dll that uses deleted controls.
  3. add empty control and public members declarations to NET9, copying them from release/3.0 branch. All methods would throw a PlatformNotSupportedException
  4. all properties should be hidden from intellisense, property browser and serializers. This is achieved by setting browsable attributes to false/hide to restored members in the existing classes -
  1. Set ObsoleteAttribute, and an error message on all restored types and APIs that were re-added to the existing types. See eff830b for details.

@paul1956
Copy link
Contributor

paul1956 commented Feb 1, 2024

@Tanya-Solyanik
I just want someone to make sure that I will still be able to use the NuGet package winforms-datavisualization from https://github.com/kirsan31/winforms-datavisualization which replaced the .NET Framework datavisualization control in applications that were moved to .Net Core.

Have all the obsolete controls been open sourced?

@Tanya-Solyanik
Copy link
Member

@paul1956 - DataVisualization is out of scope of this item. This item is only about public APIs that were removed from System.Windows.Forms.dll

@JensNordenbro
Copy link

We have done the migration by reimplementing missing functionality.
Winforms gave us the worst issues so solving this is Nice.
but the re is still the life cycle issue of LTS being too short on .NET. Even If we developers love the pace of. NET, customers cant keep up. There is a need for an "eternal" Net 10 (just like Net48) for some customers to swap out Net48 and just ENJOY Windows Update security patching.

@merriemcgaw
Copy link
Member

@JensNordenbro I totally understand what you're saying here! Note that you can enable .NET updates in Microsoft Update so that servicing updates are automatically installed. We don't have an automatic upgrade between major versions, however, and you're right about the 3-year LTS cycle. We do this to help facilitate our customers keeping updated with both new functionality and the latest perf and security updates.

/cc: @jamshedd

@JensNordenbro
Copy link

Yes @merriemcgaw, I know!

Maybe it is enough, however if you want to grab the late runners I think introducing a new tier of LTS of 5 years or something is needed.

Polyfilling api:s might not be the real problem. - It helps though.

@SimonZhao888
Copy link
Member

  1. generate public API surface for NETFX 481 System.Windows.Forms.dd and for NET9 SystemWindows.Froms.dll and find public or protected APIs that we had removed
  1. System.Windows.Forms.StatusBar
    override System.Windows.Forms.StatusBar.BackColor.get -> System.Drawing.Color
    override System.Windows.Forms.StatusBar.BackColor.set -> void
    override System.Windows.Forms.StatusBar.BackgroundImage.get -> System.Drawing.Image
    override System.Windows.Forms.StatusBar.BackgroundImage.set -> void
    override System.Windows.Forms.StatusBar.BackgroundImageLayout.get -> System.Windows.Forms.ImageLayout
    override System.Windows.Forms.StatusBar.BackgroundImageLayout.set -> void
    override System.Windows.Forms.StatusBar.CreateHandle() -> void
    override System.Windows.Forms.StatusBar.CreateParams.get -> System.Windows.Forms.CreateParams
    override System.Windows.Forms.StatusBar.DefaultImeMode.get -> System.Windows.Forms.ImeMode
    override System.Windows.Forms.StatusBar.DefaultSize.get -> System.Drawing.Size
    override System.Windows.Forms.StatusBar.Dispose(bool disposing) -> void
    override System.Windows.Forms.StatusBar.Dock.get -> System.Windows.Forms.DockStyle
    override System.Windows.Forms.StatusBar.Dock.set -> void
    override System.Windows.Forms.StatusBar.DoubleBuffered.get -> bool
    override System.Windows.Forms.StatusBar.DoubleBuffered.set -> void
    override System.Windows.Forms.StatusBar.Font.get -> System.Drawing.Font
    override System.Windows.Forms.StatusBar.Font.set -> void
    override System.Windows.Forms.StatusBar.ForeColor.get -> System.Drawing.Color
    override System.Windows.Forms.StatusBar.ForeColor.set -> void
    override System.Windows.Forms.StatusBar.OnHandleCreated(System.EventArgs e) -> void
    override System.Windows.Forms.StatusBar.OnHandleDestroyed(System.EventArgs e) -> void
    override System.Windows.Forms.StatusBar.OnLayout(System.Windows.Forms.LayoutEventArgs levent) -> void
    override System.Windows.Forms.StatusBar.OnMouseDown(System.Windows.Forms.MouseEventArgs e) -> void
    override System.Windows.Forms.StatusBar.OnResize(System.EventArgs e) -> void
    override System.Windows.Forms.StatusBar.Text.get -> string
    override System.Windows.Forms.StatusBar.Text.set -> void
    override System.Windows.Forms.StatusBar.ToString() -> string
    override System.Windows.Forms.StatusBar.WndProc(ref System.Windows.Forms.Message m) -> void
    override System.Windows.Forms.StatusBarPanel.Dispose(bool disposing) -> void
    override System.Windows.Forms.StatusBarPanel.ToString() -> string
    System.Windows.Forms.StatusBar.BackColorChanged -> System.EventHandler
    System.Windows.Forms.StatusBar.BackgroundImageChanged -> System.EventHandler
    System.Windows.Forms.StatusBar.BackgroundImageLayoutChanged -> System.EventHandler
    System.Windows.Forms.StatusBar.DrawItem -> System.Windows.Forms.StatusBarDrawItemEventHandler
    System.Windows.Forms.StatusBar.ForeColorChanged -> System.EventHandler
    System.Windows.Forms.StatusBar.ImeMode.get -> System.Windows.Forms.ImeMode
    System.Windows.Forms.StatusBar.ImeMode.set -> void
    System.Windows.Forms.StatusBar.ImeModeChanged -> System.EventHandler
    System.Windows.Forms.StatusBar.Paint -> System.Windows.Forms.PaintEventHandler
    System.Windows.Forms.StatusBar.PanelClick -> System.Windows.Forms.StatusBarPanelClickEventHandler
    System.Windows.Forms.StatusBar.Panels.get -> System.Windows.Forms.StatusBar.StatusBarPanelCollection
    System.Windows.Forms.StatusBar.ShowPanels.get -> bool
    System.Windows.Forms.StatusBar.ShowPanels.set -> void
    System.Windows.Forms.StatusBar.SizingGrip.get -> bool
    System.Windows.Forms.StatusBar.SizingGrip.set -> void
    System.Windows.Forms.StatusBar.StatusBar() -> void
    System.Windows.Forms.StatusBar.TabStop.get -> bool
    System.Windows.Forms.StatusBar.TabStop.set -> void
    virtual System.Windows.Forms.StatusBar.OnDrawItem(System.Windows.Forms.StatusBarDrawItemEventArgs sbdievent) -> void
    virtual System.Windows.Forms.StatusBar.OnPanelClick(System.Windows.Forms.StatusBarPanelClickEventArgs e) -> void

  2. System.Windows.Forms.StatusBar.StatusBarPanelCollection
    System.Windows.Forms.StatusBar.StatusBarPanelCollection.Contains(System.Windows.Forms.StatusBarPanel panel) -> bool
    System.Windows.Forms.StatusBar.StatusBarPanelCollection.Count.get -> int
    System.Windows.Forms.StatusBar.StatusBarPanelCollection.GetEnumerator() -> System.Collections.IEnumerator
    System.Windows.Forms.StatusBar.StatusBarPanelCollection.IndexOf(System.Windows.Forms.StatusBarPanel panel) -> int
    System.Windows.Forms.StatusBar.StatusBarPanelCollection.IsReadOnly.get -> bool
    System.Windows.Forms.StatusBar.StatusBarPanelCollection.StatusBarPanelCollection(System.Windows.Forms.StatusBar owner) -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.Add(string text) -> System.Windows.Forms.StatusBarPanel
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.Add(System.Windows.Forms.StatusBarPanel value) -> int
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.AddRange(System.Windows.Forms.StatusBarPanel[] panels) -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.Clear() -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.ContainsKey(string key) -> bool
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.IndexOfKey(string key) -> int
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.Insert(int index, System.Windows.Forms.StatusBarPanel value) -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.Remove(System.Windows.Forms.StatusBarPanel value) -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.RemoveAt(int index) -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.RemoveByKey(string key) -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.this[int index].get -> System.Windows.Forms.StatusBarPanel
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.this[int index].set -> void
    virtual System.Windows.Forms.StatusBar.StatusBarPanelCollection.this[string key].get -> System.Windows.Forms.StatusBarPanel

  3. System.Windows.Forms.StatusBarDrawItemEventArgs
    System.Windows.Forms.StatusBarDrawItemEventArgs.Panel.get -> System.Windows.Forms.StatusBarPanel
    System.Windows.Forms.StatusBarDrawItemEventArgs.StatusBarDrawItemEventArgs(System.Drawing.Graphics g, System.Drawing.Font font, System.Drawing.Rectangle r, int itemId, System.Windows.Forms.DrawItemState itemState, System.Windows.Forms.StatusBarPanel panel, System.Drawing.Color foreColor, System.Drawing.Color backColor) -> void
    System.Windows.Forms.StatusBarDrawItemEventArgs.StatusBarDrawItemEventArgs(System.Drawing.Graphics g, System.Drawing.Font font, System.Drawing.Rectangle r, int itemId, System.Windows.Forms.DrawItemState itemState, System.Windows.Forms.StatusBarPanel panel) -> void

  4. System.Windows.Forms.StatusBarPanel
    System.Windows.Forms.StatusBarPanel.Alignment.get -> System.Windows.Forms.HorizontalAlignment
    System.Windows.Forms.StatusBarPanel.Alignment.set -> void
    System.Windows.Forms.StatusBarPanel.AutoSize.get -> System.Windows.Forms.StatusBarPanelAutoSize
    System.Windows.Forms.StatusBarPanel.AutoSize.set -> void
    System.Windows.Forms.StatusBarPanel.BeginInit() -> void
    System.Windows.Forms.StatusBarPanel.BorderStyle.get -> System.Windows.Forms.StatusBarPanelBorderStyle
    System.Windows.Forms.StatusBarPanel.BorderStyle.set -> void
    System.Windows.Forms.StatusBarPanel.EndInit() -> void
    System.Windows.Forms.StatusBarPanel.Icon.get -> System.Drawing.Icon
    System.Windows.Forms.StatusBarPanel.Icon.set -> void
    System.Windows.Forms.StatusBarPanel.MinWidth.get -> int
    System.Windows.Forms.StatusBarPanel.MinWidth.set -> void
    System.Windows.Forms.StatusBarPanel.Name.get -> string
    System.Windows.Forms.StatusBarPanel.Name.set -> void
    System.Windows.Forms.StatusBarPanel.Parent.get -> System.Windows.Forms.StatusBar
    System.Windows.Forms.StatusBarPanel.StatusBarPanel() -> void
    System.Windows.Forms.StatusBarPanel.Style.get -> System.Windows.Forms.StatusBarPanelStyle
    System.Windows.Forms.StatusBarPanel.Style.set -> void
    System.Windows.Forms.StatusBarPanel.Tag.get -> object
    System.Windows.Forms.StatusBarPanel.Tag.set -> void
    System.Windows.Forms.StatusBarPanel.Text.get -> string
    System.Windows.Forms.StatusBarPanel.Text.set -> void
    System.Windows.Forms.StatusBarPanel.ToolTipText.get -> string
    System.Windows.Forms.StatusBarPanel.ToolTipText.set -> void
    System.Windows.Forms.StatusBarPanel.Width.get -> int
    System.Windows.Forms.StatusBarPanel.Width.set -> void

  5. System.Windows.Forms.StatusBarPanelAutoSize
    System.Windows.Forms.StatusBarPanelAutoSize.Contents = 3 -> System.Windows.Forms.StatusBarPanelAutoSize
    System.Windows.Forms.StatusBarPanelAutoSize.None = 1 -> System.Windows.Forms.StatusBarPanelAutoSize
    System.Windows.Forms.StatusBarPanelAutoSize.Spring = 2 -> System.Windows.Forms.StatusBarPanelAutoSize

  6. System.Windows.Forms.StatusBarPanelBorderStyle
    System.Windows.Forms.StatusBarPanelBorderStyle.None = 1 -> System.Windows.Forms.StatusBarPanelBorderStyle
    System.Windows.Forms.StatusBarPanelBorderStyle.Raised = 2 -> System.Windows.Forms.StatusBarPanelBorderStyle
    System.Windows.Forms.StatusBarPanelBorderStyle.Sunken = 3 -> System.Windows.Forms.StatusBarPanelBorderStyle

  7. System.Windows.Forms.StatusBarPanelClickEventArgs
    System.Windows.Forms.StatusBarPanelClickEventArgs.StatusBarPanel.get -> System.Windows.Forms.StatusBarPanel
    System.Windows.Forms.StatusBarPanelClickEventArgs.StatusBarPanelClickEventArgs(System.Windows.Forms.StatusBarPanel statusBarPanel, System.Windows.Forms.MouseButtons button, int clicks, int x, int y) -> void
    System.Windows.Forms.StatusBarPanelClickEventHandler

  8. System.Windows.Forms.StatusBarPanelStyle
    System.Windows.Forms.StatusBarPanelStyle.OwnerDraw = 2 -> System.Windows.Forms.StatusBarPanelStyle
    System.Windows.Forms.StatusBarPanelStyle.Text = 1 -> System.Windows.Forms.StatusBarPanelStyle

  9. System.Windows.Forms.IDataGridEditingService
    System.Windows.Forms.IDataGridEditingService.BeginEdit(System.Windows.Forms.DataGridColumnStyle gridColumn, int rowNumber) -> bool
    System.Windows.Forms.IDataGridEditingService.EndEdit(System.Windows.Forms.DataGridColumnStyle gridColumn, int rowNumber, bool shouldAbort) -> bool

@weltkante
Copy link
Contributor

I don't think thats complete? I remember the discussion of removing the old menu APIs. So unless I'm misunderstanding what you're trying to do, shouldn't those appear on the list too?

@RussKie
Copy link
Member

RussKie commented Feb 7, 2024

You don't need to go far.

@SimonZhao888 SimonZhao888 linked a pull request Mar 11, 2024 that will close this issue
@dotnet-policy-service dotnet-policy-service bot added the 🚧 work in progress Work that is current in progress label Mar 11, 2024
@Tanya-Solyanik Tanya-Solyanik modified the milestones: .NET 9.0, .NET 10.0 Jul 23, 2024
@Tanya-Solyanik Tanya-Solyanik added api-ready-for-review (2) API is ready for formal API review; applied by the issue owner and removed api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation 🚧 work in progress Work that is current in progress labels Oct 11, 2024
@bartonjs
Copy link
Member

bartonjs commented Oct 15, 2024

Video

Bringing the types and members back to look like they did in .NET Framework is blanket approved.

The "new" types/members being declared as Obsolete with EditorBrowsable(Never) and Browsable(false) seems like goodness. While the obsoletion message makes sense to be different for each type/member (as appropriate), they should all use the same diagnostic ID as they were made obsolete in the same wave, and there's no reason to opt in to only parts of them.

[Obsolete(
    "ContextMenu and its related types has been deprecated. Use ContextMenuStrip instead.",
    error: false,
    DiagnosticId = WFDEV###,
    UrlFormat = "https://aka.ms/winforms-warnings/{0}")]
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
public partial class ContextMenu : Menu
{
    public ContextMenu() : base(items: null) => throw new PlatformNotSupportedException();
}

@bartonjs bartonjs added api-approved (4) API was approved in API review, it can be implemented and removed api-ready-for-review (2) API is ready for formal API review; applied by the issue owner labels Oct 15, 2024
@dotnet-policy-service dotnet-policy-service bot added the 🚧 work in progress Work that is current in progress label Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved (4) API was approved in API review, it can be implemented blocking-migration An issue that is preventing the developer from migrating from .NET Framework or earlier .NET 🚧 work in progress Work that is current in progress
Projects
None yet
Development

Successfully merging a pull request may close this issue.