1个子窗体从多个父窗体C#获取属性

时间:2019-05-16 07:23:50

标签: c# winforms

我能否从1个datagridview形式(FrmItemSearch)的2个父对象(FrmMasterItem)和(FrmMasterPackage)获取查询值,并将选定的值传递给其父表单 我是C#的新手:)

我已经尝试过FrmItemSearch从FrmMasterItem获取数据,它可以显示数据,但是我也想从FrmMasterPackage获取数据,所以我只需要1个gridview表单

//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;
      }
}

3 个答案:

答案 0 :(得分:1)

只需按照以下主表形式声明myQuery变量

public static string myQuery

然后您可以使用主对象访问此变量为任何形式

答案 1 :(得分:0)

我是否还可以补充一下,将DAL(数据访问层)或BLL(业务逻辑层)代码添加到表单中被认为是不好的做法吗?我建议为此类代码创建目录和类。

我建议以下内容:

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)
      {
            ataGridView1.DataSource = DAL.GetSourceFromDatabase(DAL.query);
      }
}

public static class DAL
{
    public static string query = "MyQuery"

    public static BindingSource GetSourceFromDatabase(string query)
    {
        MySqlConnection conn = DBUtils.GetDbConnection();
        conn.Open();
        MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn);
        DataTable dt = new DataTable();
        adapter.Fill(dt);
        BindingSource bSource = new BindingSource();
        bSource.DataSource = dt;
        return dt;
    }
}

答案 2 :(得分:0)

使用Interface定义将类(此处为Form)与另一个类相关的 contract 的示例。

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

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

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

    string GetSomeOtherValue();
}

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

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事件中,设置了Interface定义的属性,初始化并显示了Search表单,将Search表单设置为当前Owner

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

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

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

ISearch myOwner = null;

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

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

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

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

Search格式:

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 the not the right type!");
        }
    }
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        myOwner.ReturnValue = true;
        base.OnFormClosing(e);
    }
}