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