簡體   English   中英

"使用簡單注入器c#時從父窗體設置子winform屬性"

[英]set child winform properties from a parent form when using simple injector c#

我有一個 form1(不是 mdi),它在按鈕單擊事件上顯示對話框,對話框基本上是一個彈出窗體,它顯示 datagridview 控件上的數據。

我正在使用簡單的注射器。

PopUpForm 有一個名為 LocationData 的屬性,它是一個數據表。 我需要在 form1 (父級)中設置該屬性,以便在屏幕上顯示數據時可以在 PopUpForm 上顯示數據。

抱歉,我是簡單注射器的新手,仍在學習,任何幫助或指導將不勝感激。 我什至不知道我是否以正確的方式做事。

表格1<\/strong>

按鈕點擊事件

this._formOpener.ShowModalForm<PopUpForm>();

首先,您可能從這個答案中復制了 FormOpener 。 但是你錯過了關於表單需要是瞬態的部分。 不要將您的表單注冊為Singleton 特別是因為您處理了它們,這將一次且恰好一次地起作用。 下次您想要顯示Form您將收到ObjectDisposedException

當您將表單注冊為Transient Simple Injector 時,它會告訴您表單實現了IDisposable ,這(當然)是正確的。 但是因為您負責在FormOpener進行處理, FormOpener您可以安全地取消此警告。 像這樣注冊你的表格:

private static void RegisterWindowsForms(
      this Container container, IEnumerable<Assembly> assemblies)
{
    var formTypes =
        from assembly in assemblies
        from type in assembly.GetTypes()
        where type.IsSubclassOf(typeof(Form))
        where !type.IsAbstract
        select type;

    foreach (var type in formTypes)
    {
        var registration = Lifestyle.Transient.CreateRegistration(type, container);

        registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
            "Forms are disposed by application code. Letting Simple Injector do this " +
            "is problematic because that would need a scope, which is impossible to do.");

        container.AddRegistration(type, registration);
    }
}

來回答你的問題:你需要一些額外的基礎設施來初始化Form

通過讓您的表單實現接口IFormInit<T>您可以將數據傳遞給表單並直接顯示它。

public interface IFormInit<T> : IDisposable
{
    DialogResult InitAndShowForm(T data);
}

為了讓 Simple Injector 基於這個接口創建表單,我們需要在容器中注冊它們。 我們可以通過提供程序集列表讓 Simple Injector 搜索所有關閉的實現,如下所示:

container.Register(typeof(IFormInit<>), assemblies, Lifestyle.Transient);

請注意,Simple Injector 會自動將這些注冊與RegisterWindowsForms合並。 所以你現在可以通過調用來獲取Form的一個實例:

container.GetInstance<PopupForm>();
      or
container.GetInstance<IFormInit<SomeDataClass>>();   

您現在可以將此代碼添加到您的FormOpener類中:

public DialogResult ShowModalForm<TData>(TData data)
{
    Type formType = typeof(IFormInit<>).MakeGenericType(typeof(TData));
    dynamic initForm = this.container.GetInstance(formType);

    DialogResult result = (DialogResult) initForm.InitAndShowForm(data);

    initForm.Dispose();
    return result;
}

這將根據它實現的IFormInit<T>類型從容器中獲取Form 拿到表單后,調用界面上的函數,而不是直接調用Form.ShowDialog() 當表單關閉時,您將處理該表單。

注意: dynamic類型的使用可能需要澄清。 為什么需要它的靈感來自此處描述的QueryHandler模式。

用法如下:

// Add a specific class to pass to the form
public class LocationDataWrapper
{
    public DataTable LocationData { get; set; }
}

public partial class PopUpForm : Form, IFormInit<LocationDataWrapper>
{
    public PopUpForm() => InitializeComponent();

    // Implement the interface, the loaded event can be removed
    public DialogResult InitAndShowForm(LocationDataWrapper data)
    {
        dgvNearestLocations.DataSource = data.LocationData;
        return this.ShowDialog();
    }
}

按鈕點擊事件

DialogResult result = this._formOpener.ShowModalForm(new LocationDataWrapper
{
    LocationData = locationDataTable,
});

您可以為每個表單創建包裝器或數據類,當您讓此Form實現IFormInit<ThisSpecificDataClass>時,它會自動顯示正確的表單。

我知道這有點老話題了,但是如果項目包含多個 DLL,我如何獲取這些 DLL 的表單類型以便RegisterWindowsForms<\/code>方法注冊它們? 另外,如果這些 DLL 還沒有加載,有可能嗎?

"

暫無
暫無

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

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