>source

버튼 클릭 이벤트에 대화 상자를 표시하는 form1 (mdi가 아님)이 있으며 대화 상자는 기본적으로 datagridview 컨트롤에 대한 데이터를 표시하는 팝업 양식입니다.

간단한 인젝터를 사용하고 있습니다.

PopUpForm에는 데이터 테이블 인 LocationData라는 속성이 있습니다. 데이터가 화면에 표시 될 때 PopUpForm에 표시 될 수 있도록 form1 (부모)에 해당 속성을 설정해야합니다.

죄송합니다, 저는 간단한 인젝터를 처음 사용하며 여전히 배우고 있습니다. 어떤 도움이나 안내를 주시면 감사하겠습니다. 나는 내가 옳은 일을하고 있는지조차 모른다.

form1

버튼 클릭 이벤트

this._formOpener.ShowModalForm<PopUpForm>();

PopUpForm

public partial class PopUpForm : Form
{
    public DataTable LocationData { get; set; }
    public PopUpForm()
    {
        InitializeComponent();
    }
    private void PopUpForm_Load(object sender, EventArgs e)
    {
        dgvNearestLocations.DataSource = LocationData;
    }
}

프로그램 수업

static class Program
{
    private static Container container;
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Bootstrap();
        Application.Run(container.GetInstance<Form1>());
    }
    private static void Bootstrap()
    {
        // Create the container as usual.
        container = new Container();
        // Register your types, for instance:
        container.RegisterSingleton<IFormOpener, FormOpener>();
        container.Register<Form1>(Lifestyle.Singleton); ;
        container.Register<PopUpForm>(Lifestyle.Singleton); ;
        // Optionally verify the container.
        container.Verify();
    }
}

FormOpener

public class FormOpener : IFormOpener
{
    private readonly Container container;
    private readonly Dictionary<Type, Form> openedForms;
    public FormOpener(Container container)
    {
        this.container = container;
        this.openedForms = new Dictionary<Type, Form>();
    }
    public DialogResult ShowModalForm<TForm>() where TForm : Form
    {
        using (var form = this.GetForm<TForm>())
        {
            return form.ShowDialog();
        }
    }
    private Form GetForm<TForm>() where TForm : Form
    {
        return this.container.GetInstance<TForm>();
    }
}

  • 답변 # 1

    우선, 아마도이 답변에서 FormOpener를 복사했습니다. 그러나 일시적인 양식이 필요한 부분을 놓쳤습니다. 양식을 다음과 같이 등록하지 마십시오. Singleton . 특히 당신이 그들을 처분하기 때문에 이것은 정확히 한 번 작동합니다. 다음에 보여주고 싶을 때 Form 당신은 얻을 것이다 ObjectDisposedException .

    양식을 다음으로 등록 할 때 Transient Simple Injector는 양식이 IDisposable 그리고 이것은 (물론) 정확합니다. 그러나 당신이 처분을 처리하기 때문에 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;
    }
    
    

    이것은 얻을 것이다 Form 컨테이너에서 IFormInit<T> 구현하는 유형. 양식을 받으면 직접 호출하는 대신 인터페이스에서 함수를 호출합니다. 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> .

관련 자료

  • 이전 Python에서 중첩 된 JSON (?) 객체 구문 분석
  • 다음 C #의 하위 폼에서 클래스 인스턴스의 함수 호출