简体   繁体   中英

C# WinForms Control on order changed event

I have a WinForms application with a custom "tab" concept, in that there are 3 buttons that call their respective panels "BringToFront()" method.

As these panels are all initialised when the Form is initialised, but contain separate functionality of their own, I don't want to initialise some of the more intensive tasks until that Panel has been "switched" to.

For example, one of my Panels has a Twitter connection functionality. If I initialise the Twitter connection on the Panel initialisation, it may fail while in theory the user is on a completely different panel/functionality.

I only want it to try to connect to Twitter once the user has come to this panel.

So, I've been reading through MSDN but can't find an event that fires when a Controls display order has been changed.

I've come across these events, but not sure which/if at all, these work or are best:

Panel.OnVisibleChanged Panel.OnEnter Panel.OnGotFocus

I'm still learning C#, so any help/comments is appreciated.

I had the same problem and I fixed it by making each tab to implement an interface and trigering it whenever i try to load it (i hope that makes sense)( https://github.com/WithoutCaps/LimitlessUI/blob/master/LimitlessUI/TabsAdapter_WOC.cs )

lines 30/31

if(tab is Tab_WOC)
     ((Tab_WOC)tab).onShowTab();

feel free to use this code/library

NOTE: there is demo app too!

This problem is a good example for back ground task. Once you feel current panel's properties are set, you can start initializing the other panels in background. Panel's tag property can be used to preserve a boolean value if its set or not. Moreover, you can hide and show the panel's rather than BringToFront. This will fire the VisibleChanged event and easy to capture and process once they are visible. This is to show you how background worker code will be.

private void BackgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        if (!Convert.ToBoolean(Panel1.Tag)) {
            //Intialize panel1
            Panel1.Tag = true;
        }
        if (!Convert.ToBoolean(Panel2.Tag)) {
            //Intialize panel2
            Panel2.Tag = true;
        }
        if (!Convert.ToBoolean(Panel3.Tag)) {
            //Intialize panel3
            Panel3.Tag = true;
        }
    }

Obviously I do not know how you have your project laid out but I see two options.

Option 1: Property that lazy loads

Create a property that when you call it checks to see if a field is null and if it is, initialize it with a call to whatever expensive class constructor you want.

public TwitterCommunicator TwitterCommunicator => _twitterCommunicator ?? (_twitterCommunicator = new TwitterCommunicator());

public void AnotherTwitterPanelMethod()
{
    TwitterCommunicator.LoadTweets();
}

Option 2: Use Lazy<T>

Similar to lazy loading property. Actually use Lazy which provides lazy initialization of your object when you actually want it to initialize.

public partial class MainForm : Form
{
    public MainForm()
    {
        Lazy<TwitterCommunicator> _lazyTwitter = new Lazy<TwitterCommunicator>();
    }
}

public void SomeTwitterPanelMethod()
{
    _lazyTwitter.Value.LoadTweets();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM