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

UI Layout broken in later previews. #1827

Closed
CodedBeard opened this issue Sep 9, 2019 · 12 comments
Closed

UI Layout broken in later previews. #1827

CodedBeard opened this issue Sep 9, 2019 · 12 comments
Assignees
Labels
tenet-compatibility Incompatibility with previous versions or with WinForms for .NET Framework

Comments

@CodedBeard
Copy link

CodedBeard commented Sep 9, 2019

  • .NET Core Version: 3.0 preview 9
  • Have you experienced this same bug with .NET Framework?: No

Problem description:
We are porting a .Net framework winforms app to core. Up until preview 6, all of the ui was working exactly the same to .net framework, but since preview 6 we've started encountering various things that no longer behave as before. The first example is on the start form for the application, where the menu panel is no longer centered correctly.

Expected behavior: .NET Framework and Core 3.0 previews 1-5 look like this
preview5

Actual behavior: Preview 6-9 do this
preview9

Minimal repro:
uibug.zip

@kirsan31
Copy link
Contributor

kirsan31 commented Sep 9, 2019

We have 2 problems here.

  1. Centering issue. Appear only if WindowState = System.Windows.Forms.FormWindowState.Maximized;
  2. Controls size issue. All controls is bigger on core. For example, main form grow from 864x740 to 1101х958.
    Snipaste_2019-09-09_17-40-18

Upd.

The problem in this line of code in Form1.Designer.cs (using depreciated AutoScaleBaseSize):
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
And different DPI policies between .net and core.

But I think we still need an answer is this expected behavior or not.

@RussKie
Copy link
Member

RussKie commented Sep 9, 2019

2. Controls size issue. All controls is bigger on core. For example, main form grow from 864x740 to 1101х958.

This is by design due to the change of the DefaultFont (#656).
More information is here dotnet/docs#14143

@RussKie
Copy link
Member

RussKie commented Sep 9, 2019

As pointed the issue disappears if this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); line is commented out in the form's designer.

@dreddy-work any thoughts?

@RussKie
Copy link
Member

RussKie commented Sep 9, 2019

If you look at the code there are few things to note:

https://github.com/dotnet/winforms/blob/master/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs#L521-L547

  1. we strongly recommend to upgrade to AutoScaleDimensions property
  2. if AutoScaleBaseSize isn't explicitly set, it gets calculated based on the form's font: https://github.com/dotnet/winforms/blob/master/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs#L543
  3. GetAutoScaleSize is marked as obsolete and instead recommends AutoScaleDimensions instead: https://github.com/dotnet/winforms/blob/master/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs#L3879-L3881

So it looks like a designer issue that can be resolved by removing the offending line. I'm not quite sure what other fix we can offer.
@dotnet/dotnet-winforms any thoughts?

@DustinCampbell how does the new designer handle this property?

@OliaG this is something you may wish to document as well.

@RussKie RussKie added needs-more-info tenet-compatibility Incompatibility with previous versions or with WinForms for .NET Framework labels Sep 9, 2019
@DustinCampbell
Copy link
Member

The new designer would do the same thing, though it could be changed to something else if there's a need.

@RussKie
Copy link
Member

RussKie commented Sep 9, 2019

Given that the codepath appears to be using obsolete API, should the new designer remove AutoScaleBaseSize property and replace it with AutoScaleDimensions?
Users will still need to remove AutoScaleBaseSize but at least if they opened a form in the designer and then save it, the designer would fix it for them.

@CodedBeard
Copy link
Author

Thanks for pointing out where this issue was occurring, I spent many hours trying to figure out which bit was causing it before logging this. Replacing all the calls with AutoScaleDimensions does seem to have resolved most of the UI issues. You mention these API's are obsolete, however that doesn't appear to be surfaced in the VS warnings list like i would have expected. Should it be?

There is one other major UI issue we have noticed since going past preview 5. We have a DataGrid that applies a table style which resizes the columns based on the content. Once going past preview 5, any forms with this DataGridTableStyle hang upon first load and cause the form to flicker, however if you then close the form and reopen it again the form loads and works correctly.

This is the code for the DataGridTableStyle:

public DataGridTableStyle DataGridApplyAutomaticWidths(DataGrid DataGrid, int NumberOfRowsToScan, int MaxPixelWidth)
        {
            // Create graphics object for measuring widths.
            var Graphics = DataGrid.CreateGraphics();
            // Define new table style.
            var TableStyle = new DataGridTableStyle();
            try
            {
                DataTable DataTable;
                DataTable = ((DataTable)DataGrid.DataSource).DataSet.Tables[0];
                // Can only scan rows if they exist.
                NumberOfRowsToScan = Math.Min(NumberOfRowsToScan, DataTable.Rows.Count);
                // Clear any existing table styles.
                DataGrid.TableStyles.Clear();
                // Use mapping name that is defined in the data source.
                TableStyle.MappingName = DataTable.TableName;
                // Now create the column styles within the table style.

                // Dim ColumnStyle As DataGridTextBoxColumn
                MultiLineColumn ColumnStyle;
                int Width;
                foreach (DataColumn Column in DataTable.Columns)
                {
                    // ColumnStyle = New DataGridTextBoxColumn
                    ColumnStyle = new MultiLineColumn();
                    {
                        var withBlock = ColumnStyle;
                        withBlock.TextBox.Enabled = true;
                        withBlock.HeaderText = Column.ColumnName;

                        // Column Name Conversion
                        switch (Column.ColumnName)
                        {
                            case "CallDate":
                                {
                                    withBlock.HeaderText = "Call Date";
                                    break;
                                }

                            case "CallTime":
                                {
                                    withBlock.HeaderText = "Call Time";
                                    break;
                                }

                            case "BiffpackPerson":
                                {
                                    withBlock.HeaderText = "Biffpack User";
                                    break;
                                }

                            case "CustomerName":
                                {
                                    withBlock.HeaderText = "Customer Name";
                                    break;
                                }

                            case "CallLogCategory":
                                {
                                    withBlock.HeaderText = "Category";
                                    break;
                                }
                        }

                        withBlock.MappingName = Column.ColumnName;
                        // Set width to header text width.
                        Width = (int)Graphics.MeasureString(withBlock.HeaderText, DataGrid.Font, MaxPixelWidth).Width;
                    }
                    // Change width, if data width is wider than header text width.
                    // Check the width of the data in the first X rows.
                    int iRow;
                    DataRow DataRow;
                    for (iRow = 0; iRow <= NumberOfRowsToScan - 1; iRow++)
                    {
                        DataRow = DataTable.Rows[iRow];
                        if (!IsDBNull(DataRow[Column.ColumnName]))
                            Width = (int)Math.Max(Width, Graphics.MeasureString(DataRow[Column.ColumnName].ToString(), DataGrid.Font, MaxPixelWidth).Width);
                    }
                    ColumnStyle.Width = Width + 4;
                    // Add the new column style to the table style.
                    TableStyle.GridColumnStyles.Add(ColumnStyle);
                }
                // Add the new table style to the data grid.
                DataGrid.TableStyles.Add(TableStyle);
                // Resize Last Column
                var intNumCols = ((DataTable)DataGrid.DataSource).Columns.Count;
                var intTargetWidth = DataGrid.ClientSize.Width - SystemInformation.VerticalScrollBarWidth - 4;
                var intRunningWidthUsed = DataGrid.TableStyles[DataTable.TableName].RowHeaderWidth;
                for (var ii = 1; ii <= intNumCols - 1; ii++)
                    intRunningWidthUsed += DataGrid.TableStyles[DataTable.TableName].GridColumnStyles[ii - 1].Width;
                if ((intRunningWidthUsed < intTargetWidth))
                    DataGrid.TableStyles[DataTable.TableName].GridColumnStyles[intNumCols - 1].Width = intTargetWidth - intRunningWidthUsed;
            }
            finally
            {
                Graphics.Dispose();
            }
            return TableStyle;
        }

Is there anything you can spot that has changed since preview 5, that could cause such an issue? As it doesn't seem to be being caused by the AutoScaleBaseSize unlike the rest.

Also is there a list anywhere that we can see all the things that have changed regarding UI for core 3? Almost all of the winforms apps we have that need converting are very old (most never went past .net 1) so having all the things to check in one place would be much appreciated.

@RussKie
Copy link
Member

RussKie commented Sep 10, 2019

There is one other major UI issue we have noticed since going past preview 5. We have a DataGrid that applies a table style which resizes the columns based on the content. Once going past preview 5, any forms with this DataGridTableStyle hang upon first load and cause the form to flicker, however if you then close the form and reopen it again the form loads and works correctly.

Please raise a new issue providing as much information as possible and a repro app, and we'll have a look at it.

@RussKie
Copy link
Member

RussKie commented Sep 10, 2019

Also is there a list anywhere that we can see all the things that have changed regarding UI for core 3?

I don't think there is a document avialable that lists all changes.
You can browse issues fixed/changes accepted in each milestone:

For the most part Windows Forms on .NET Core 3.0 is about providing an API parity with the .NET Framework (4.7.2/4.8) and porting missing bits and pieces. It is possible that few APIs are still missing, but based on the data we have collected those API weren't widely used.
Another significant area of focus for us was increasing an automated test coverage to reduce the load on our testing team.

Also it is worth noting that a number of changes have been made down in the stack (i.e. in the CoreFx and CoreCLR) which we have little-to-no visibility of, and thus things can break unbeknown to us (e.g. #242).
I know it is of little comfort to our users, but it is what it is.

And lastly, if you think something is broken in our code (not totally impossible) and it is blocking you, you can pull this repo down, run .\build-local.ps1, refernce the built assets and step through the code to see what isn't working as expected.
Contributions are quite welcome 😉

@CodedBeard
Copy link
Author

Thanks @RussKie.

I'll open another issue if I can't find what’s causing the grid problem, but its a lot harder to make a clean repro for, so will have a bit more of a dig first. Just thought I’d check it wasn't anything obviously wrong in that code along the same lines.

For the most part Windows Forms on .NET Core 3.0 is about providing an API parity with the .NET Framework (4.7.2/4.8) and porting missing bits and pieces.

Yep completely understand. I've been really impressed with just how little has gone wrong considering this app hasn't been updated in almost 15 years. Awesome job by the team!

And lastly, if you think something is broken in our code (not totally impossible) and it is blocking you, you can pull this repo down, run .\build-local.ps1, refernce the built assets and step through the code to see what isn't working as expected.

Point taken. Despite having been using core since the dnx days, I still forget that that’s an option :)

@merriemcgaw
Copy link
Member

@CodedBeard if you've got what you need with this issue, I'm going to go ahead and close it.

@RussKie RussKie closed this as completed Sep 24, 2019
@RussKie
Copy link
Member

RussKie commented Sep 24, 2019

It is worth noting that AutoScaleDimensions can yield unexpected results as well - #1948 (comment).

@ghost ghost locked as resolved and limited conversation to collaborators Feb 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
tenet-compatibility Incompatibility with previous versions or with WinForms for .NET Framework
Projects
None yet
Development

No branches or pull requests

5 participants