簡體   English   中英

WinForms設計器呈現控件之前如何運行初始化代碼?

[英]How to run initialization code before the WinForms designer renders my controls?

問題: WinForms設計器啟動時,在開始呈現表單/控件之前,有什么方法可以運行一些初始化代碼嗎? 我通常會在Program.cs的入口點執行的操作。

我的具體情況:

我有一個控制容器的倒置(我正在使用SimpleInjector),我在程序運行時進行引導。 我在Program.cs入口點之后立即執行此操作:

Container.Register<IDockingManager, DockingManagerImpl>(Lifestyle.Singleton);

在某些控件的構造函數或Load事件處理程序中,我使用容器獲取某些對象的實例:

DockingManager = IOCC.Container.GetInstance<IDockingManager>();

如果沒有在接口中注冊具體的實現,則此方法不起作用。 通常,它將在入口點進行注冊,但是設計人員不會在Program.cs運行代碼。 結果是設計器由於異常而無法呈現我的控件:

找不到IDockingManager類型的注冊。 請注意,您要解析的容器實例不包含注冊。 可能是您不小心創建了一個新的空容器嗎?

我當前的hacky解決方案:

在靜態構造函數中,我正在檢查進程名稱,以查看Visual Studio是否正在運行我的代碼。 如果是這樣,我假設代碼正在由設計人員運行,然后運行初始化代碼。 我還必須檢查我的容器是否已經初始化,因為設計器出於某種原因可以多次運行靜態構造函數,同時保持類的靜態狀態(這是一個錯誤嗎?)

static IOCC()
{
    if(Initialized)
    {
        return;
    }
    Container = new Container();
    if (IsInDesignMode())
    {
        RegisterTypes();
    }
    Initialized = true;
}

private static bool Initialized { get; }
public static Container Container { get; }

private static bool IsInDesignMode()
{
    using (var process = Process.GetCurrentProcess())
    {
        return process.ProcessName == "devenv";
    }
}

public static void RegisterTypes()
{
    Container.Register<IDockingManager, DockingManagerImpl>(Lifestyle.Singleton);
    // ...
}

這感覺很hacky,甚至不總是有效。 靜態構造函數有時由於某種原因而沒有運行,要修復它,我必須重新構建項目。 有沒有更好的方法為設計器運行初始化代碼?

希望我能正確理解您的要求:

這些功能停止呈現GUI。 那是你想要的嗎?

     [DllImport("user32.dll", EntryPoint = "SendMessageA", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
    private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
    private const int WM_SETREDRAW = 0xB;

    public static void SuspendDrawing(this Control target)
    {
        SendMessage(target.Handle, WM_SETREDRAW, 0, 0);
    }

    public static void ResumeDrawing(this Control target) { ResumeDrawing(target, true); }
    public static void ResumeDrawing(this Control target, bool redraw)
    {
        SendMessage(target.Handle, WM_SETREDRAW, 1, 0);

        if (redraw)
        {
            target.Refresh();
        }
    }

用法:

cstrctor()
{    
  //Designer is the static class which holdes these funcs 
  Designer.SuspendDrawing(this);
  //run some code here
   Designer.ResumeDrawing(this);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM