子窗体从多个父窗体获取属性 [英] Child Form getting properties from multiple parent Forms

查看:51
本文介绍了子窗体从多个父窗体获取属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以从两个父级( FrmMasterItem FrmMasterPackage )获取一个包含DataGridView的窗体( FrmItemSearch )的查询值并传递选择值到其父窗体?

Can I get query value from two parents (FrmMasterItem and FrmMasterPackage) for one Form (FrmItemSearch) that contains a DataGridView and pass the selected value to its parent Form?

我已经尝试过让 FrmItemSearch FrmMasterItem 中获取一些数据,并且它可以显示数据,但是我想让 FrmItemSearch 来获取数据也来自 FrmMasterPackage ,因此我只需要一个带有DataGridView的窗体即可执行所有搜索操作.

I've already tried tto have FrmItemSearch get some data from FrmMasterItem and it can show the data, but I want FrmItemSearch to get data from FrmMasterPackage too, so I only need one Form with a DataGridView to perform all the search operations.

//this is my MasterItem Form
public partial class FrmMasterItem : Form
{
      public string myQuery { get; set; }
      public FrmMasterItem() { InitializeComponent(); }

      public void SearchItemCode_Click(object sender, EventArgs e)
      {
            this.myQuery = "select * from InItemMst";

            FrmItemSearch fcd = new FrmItemSearch(this);
            fcd.ShowDialog();
      }
}


//this is my MasterPackage Form
public partial class FrmMasterPackage : Form 
{
    public string sQuery { get; set; }
    public FrmMasterPackage() { InitializeComponent(); }

    public void SearchItemCode_Click(object sender, EventArgs e)
    {
          this.sQuery = "select * from InPackagehdr";
          //I want to get this query on FrmSearchItem
    }
}  

//this is my Item Search Form
public partial class FrmItemSearch : Form
{
      private FrmMasterItem f_mb;
      public FrmItemSearch(FrmMasterItem fmb)
      {
            f_mb = fmb;
            InitializeComponent();
      }

      private void FrmItemSearch_Load(object sender, EventArgs e)
      {
            MySqlConnection conn = DBUtils.GetDbConnection();
            conn.Open();

            string query = this.f_mb.myQuery;//this is only MasterItem Data i want to make some selection for MasterPackage here so the Gridview can View MasterPackage data using sQuery Value from FrmMasterPackage

            MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn);
            DataTable dt = new DataTable();
            adapter.Fill(dt);
            BindingSource bSource = new BindingSource();
            bSource.DataSource = dt;
            dataGridView1.DataSource = bSource;
      }
}

推荐答案

使用接口,以定义将类(此处为表单)与另一个类相关联的合约.

An example using an Interface, to define a contract that relates a class (a Form, here) to another.

由于您有多个类(窗体)需要使用另一类(您的 Search 窗体)来使用通用属性和方法执行相同的任务,因此 worker 类( Search 表单)不需要知道实例化了哪个类,它只需要依赖Interface实现并使用通用的属性和方法来读取所需的值并写入其结果..

Since you have more than one class (Forms) that need use another class (your Search Form) to perform the same task using common properties and methods, the worker class (the Search Form) doesn't need to know which class instantiated it, it just need to rely on the Interface implementation and use the common properties and methods to read the values it needs and write its results.

创建一个接口,该接口定义创建 contract 的属性和方法(所有涉及的类都需要了解和依赖):

Create an Interface that defines the properties and methods that create the contract (what all the involved classes need to know and rely upon):

internal interface ISearch
{
    string Query { get; }
    int Other { get; }
    bool ReturnValue { get; set; }

    string GetSomeOtherValue();
}

所有要调用 Search 表单的表单都必须实现 ISearch 接口:

All the Forms that want to call the Search Form must implement the ISearch interface:

public class FrmMasterItem : Form, ISearch
{
    public FrmMasterItem() => InitializeComponent();

    // Interface implementation
    public string Query { get; private set; }
    public int Other { get ; private set; }
    public bool ReturnValue { get; set; }

    public string GetSomeOtherValue()
    {
        return "SomeValue";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.Query = "SELECT someField FROM someTable";
        this.Other = 100;
        var search = new SearchForm();
        search.ShowDialog(this);
        if (this.ReturnValue)
            Console.WriteLine("All Good");
    }
}

在这里,在 Button.Click 事件上,设置了接口定义的属性,初始化并显示了 Search 表单,并设置了 Search 当前表单所有者:

Here, on a Button.Click event, the properties defined by the Interface are set, the Search Form is initialized and shown, setting the Search Form current Owner:

var search = new SearchForm();
search.ShowDialog(this);

关闭 Search 表单时,将由 Search 表单设置的值(此处为 ReturnValue 属性值将被读取以确定搜索结果.
当然,您可以返回任何其他内容或设置多个属性:例如,可以返回一个DataTable.

When the Search Form is closed, a value set by the Search Form (here, the ReturnValue propeprty value) is read to determine the result of the search.
Of course you could return anything alse or set more than one property: you could return a DataTable, for example.

搜索表单使用界面定义了当前的调用者表单:

The Search Form defines the current caller Form using the Interface:

ISearch myOwner = null;

然后验证当前所有者是否实现此接口:它必须知道它是否可以依赖 contract 定义的属性和方法.

Then verifies whether the current owner implements this interface: it must know if it can rely on properties and methods defined by the contract.

Type type = this.Owner.GetType();
if (typeof(ISearch).IsAssignableFrom(type)) {
    // (...)
    myOwner = (ISearch)this.Owner;
}

如果当前所有者未实现受信任的接口,则会引发异常: Search 表单无法读取和写入所需的值.
如果是这样,则会自行进行初始化,以从已知属性中读取值(当然,需要进行一些常规检查,即 null 或与类型相关的值).
关闭时,它将使用特定属性(此处为 ReturnValue )设置结果:

If the current owner doesn't implement the trusted Interface, then an exception is thrown: the Search Form cannot read and write the required values.
If it does, initializes inself reading the values from the known properties (some usual checks, i.e., null or type-related, are of course needed).
When closing, it sets the result using a specific property (ReturnValue, here):

myOwner.ReturnValue = true;
base.OnFormClosing(e);

搜索表单:

public partial class SearchForm : Form
{
    ISearch myOwner = null;
    string currentQuery = string.Empty;
    string otherValues = string.Empty;

    public SearchForm() => InitializeComponent();

    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        Type type = this.Owner.GetType();
        if (typeof(ISearch).IsAssignableFrom(type))
        {
            myOwner = (ISearch)this.Owner;
            this.currentQuery = myOwner.Query;
            this.otherValues = myOwner.GetSomeOtherValue();
            Console.WriteLine(this.currentQuery);
            Console.WriteLine(myOwner.Other);
            Console.WriteLine(this.otherValues);
        }
        else
        {
            throw new NotSupportedException("My Owner is not the right type!");
        }
    }
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        myOwner.ReturnValue = true;
        base.OnFormClosing(e);
    }
}

这篇关于子窗体从多个父窗体获取属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆