[英]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.