开发者

When is Control.Visible = true turns out to be false?

I have a C# WinForms project that's very wizard like in its functionality. The individual steps live on a class called StepPanel, which inherits from the Panel control, within the form and those panels are organized in an array.

What I've run into is that when UpdateUI() is called and walks the array, adjusts the wizards step title text for the current ste开发者_C百科p, it makes sure that all of the inactive steps are hidden, and ensures that the active step is visible, in the right spot, and is the right size.

Here's the code:

    private void UpdateUI()
    {
        // If the StepIndex equals the array length, that's our cue 
        // to exit.
        if (StepIndex == Steps.Length)
        {
            Application.Exit();
            return;
        }

        for (var xx = 0; xx < Steps.Length; xx++)
        {
            if (xx == StepIndex)
            {
                if (!String.IsNullOrEmpty(Steps[xx].Title))
                {
                    LabelStepTitle.ForeColor = SystemColors.ControlText;
                    LabelStepTitle.Text = Steps[xx].Title;
                }
                else
                {
                    LabelStepTitle.ForeColor = Color.Red;
                    LabelStepTitle.Text =
                        Resources.UiWarning_StepTitleNotSet;
                }
            }
            else
            {
                Steps[xx].Visible = false;
            }
        }

        Steps[StepIndex].Top = 50;
        Steps[StepIndex].Left = 168;
        Steps[StepIndex].Width = 414;
        Steps[StepIndex].Height = 281;
        Steps[StepIndex].Visible = true;

        SetNavigationButtonState(true);
    }

When everything is said and done, Steps[StepIndex].Visible == false.

I'm still perplexed by this behavior because I was working less than 30 minutes ago.


If you set a parent/container control to Visible = false then setting any child controls to Visible = true will have no effect what so ever. The Visible property of the child control will still be false.

I don't know if it's what happens in this case since I don't know the structure of the controls but it seems to be a likely scenario.

To solve this you need to first set the parent/contianer control to Visible = true and THEN the child control(s).


if (xx == StepIndex)

Is only going to be true and the end of the loop unless I am missing something.


There are several possibilities. When you attach a debugger on the line:

SetNavigationButtonState(true);

does Steps[StepIndex].Visible == true? If so, then make sure that StepIndex is actually the index you expected (not off by 1, and not reflecting the "previous" step). If you verify that the correct step is set to true, then you must be updating it somewhere else.

if Steps[StepIndex].Visible == false right after you set it to true, then either the getter on the Visible property is returning based on some calculation or an event was triggered that is changing it back to false.

HTH.


I encountered same issue using MDIForm in VB.net and Sani Singh Huttunen explanation is correct for me.

I post this answer to give more explanations and also a specific solution or a work around.

When I click on a specific menu to load a new MDI Child form, my program excute following code

Dim frm As New FrmPaiement
frm.MdiParent = Me
Call frm.NewRecord()
Call ReorganizeControlTopPositions(frm.DataPanel)
frm.Show()

where FrmPaiement is a Form class that originally contains a lot of controls and DataPanel is central panel that contains all data TextBox, CheckBox, ComboBox and DateBox controls.

When is Control.Visible = true turns out to be false?

But these time, some controls are hidden in frm.NewRecord() function.

When is Control.Visible = true turns out to be false?

ReorganizeControlTopPosition() function is called to reduce gaps between remainding visible controls

When is Control.Visible = true turns out to be false?

For information, VB.Net code of ReorganizeControlTopPositions() is following

Public Sub ReorganizeControlTopPositions(ctlContainer As Panel)
    'Put all controls in a List(Of Control) and sort it on Top position
    For Each ctl As Control In ctlContainer.Controls
        lstControls.Add(ctl)
    Next

    lstControls.Sort(Function(x, y) x.Top.CompareTo(y.Top))

    'Reduce gaps between 2 visibles controls

    Dim iLastTop As Integer = -1
    Dim nInvisible = 0
    Dim iLastControlTop As Integer = 0

    For Each ctl In lstControls
        If nInvisible > 0 Then
            If ctl.Visible Then
                If ctl.Top = iLastControlTop Then
                    ctl.Top = iLastTop
                Else
                    iLastControlTop = ctl.Top
                    ctl.Top = iLastTop + 32
                End If
            End If
        End If

        If ctl.Visible Then
            iLastTop = ctl.Top
        Else
            nInvisible += 1
        End If
    Next

End Sub

EXPLANATION OF ERROR

Since ReorganizeControlTopPositions() function is called before frm.Show() function, MDI Child is hidden and in debug mode, ctl.Visible contains always False !

If initialisation code if changed so that ReorganizeControlTopPositions() is called after frm.Show() call, program runs correctly and ctl.Visible contains "correct" value.

Dim frm As New FrmPaiement
frm.MdiParent = Me
Call frm.NewRecord()
frm.Show()
Call ReorganizeControlTopPositions(frm.DataPanel)

The only problem is that MDI Form is shortly (very quicly) displaying controls with gaps and a micro secund later without gaps.

The problem is linked to Microsoft implementation of Visible property.

Setting Visible property seems to change visible value of control but getting Visible value return only True if Visible property of control is True and also all containers containing this control are visibles !

What is written on Control.Visible property on learn.microsoft.com is extremly confuse !!!

Return True if the control and all its child controls are displayed; otherwise, false. The default is true.

The correct definition sould be

Return True if the control and all its PARENT controls are displayed; otherwise, false. The default is true.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜