WinForm - 复制带有OWN行为的TabControl

时间:2017-05-30 21:46:39

标签: c# duplicates copy tabcontrol

Copy TabControl Tab是的,我已经检查了这个。

我正在尝试复制一个tabcontol但这个标签应该有它自己的'行为'。

        TabControl tc = TC_Fields;
        TabPage tpOld = tc.TabPages[0];

        TabPage tpNew = new TabPage();

        fields += 1;
        tpNew.Name = "Field_" + fields;
        tpNew.Text = "Field-" + fields;

        foreach (Control c in tpOld.Controls)
        {
            Control cNew = (Control) Activator.CreateInstance(c.GetType());
            PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(c);
            foreach (PropertyDescriptor entry in pdc)
            {
                object val = entry.GetValue(c);
                if (entry.Name == "Name")
                {
                    val = (String) val + fields;    
                }
                entry.SetValue(cNew, val);
            }
            tpNew.Controls.Add(cNew);
        }

        tc.TabPages.Add(tpNew);

我已经尝试了上面的代码,因此它为新控件提供了一个新的“id”,但我仍然无法单击新选项卡中的控件,它们只模仿第一个选项卡中的内容。

有没有办法可以复制所有控件而不是模仿它们被复制的控件?

2 个答案:

答案 0 :(得分:1)

  1. 您的代码至少有两个与实际问题无关的问题。让我们先解决其中两个问题:

    • 您可以设置所有属性,即使是您不应该设置的属性;最值得注意的是,你不应该触摸"WindowTarget"财产!它仅供内部使用,并且与它混乱将至少阻止一些控制工作。我发现我无法检查CheckBox,例如。

    • 如果原始TabPage也是当前,那么您的代码只会创建可见控件。所有其他页面上的所有控件都是不可见的,如果您尝试克隆任何其他页面TabPage,则所有控件都会添加得很好但保持不可见

  2. 让我们添加一个过滤器:

    if(entry.Name != "WindowTarget")     entry.SetValue(cNew, val);
    

    并使新控件可见:

    cNew.Visible = true;
    tpNew.Controls.Add(cNew);
    

    请注意,这是一个简单的解决方案,因为它还会使那些最初看不见的控件可见。您可以改为显示要克隆的页面或列出不可见的控件;用他们的名字你可以找到克隆的对应物..

    最后一个问题也很重要,但不仅仅是问题:代码只会直接在页面上克隆控件,而不是任何新的控件(如RadioButtons中的GroupBox!)。为此,您必须编写递归版本!

    1. 现在提出一个实际问题:你如何给克隆控件提供自己的行为?
    2. 克隆所有属性之后,它们就像新添加的控件一样,即它们根本没有事件处理程序

      所以你需要

      • 为新控件的事件
      • 编写新的事件处理程序
      • 把它们连接起来

      虽然这不是很难,但是有很多问题......

      我们知道命名方案,因此我们可以知道我们想要为事件提供哪些控件。事件名称可以自由选择,但要将它们连接起来,我们需要知道我们正在处理哪些新控件..

      以下是与Button cb_hello事件挂钩的{strong>第一个克隆的示例:

      Click

      事件中的代码演示了更多问题:

        if (cNew.Name == "cb_hello1") cNew.Click += buttonNew_Click;
      

      在将private void buttonNew_Click(object sender, EventArgs e) { Button btn = sender as Button; Console.WriteLine(btn.Name + " says hiho"); btn.Parent.Controls["panel41"].BackColor = Color.ForestGreen; ((RadioButton)btn.Parent.Controls["radioButton11"]).Checked = true; } 转换为sender时非常正常,当我们尝试访问我们刚刚克隆的任何控件时,我们会遇到麻烦:

      • 由于它们是动态创建的,因此我们无法使用变量访问其中任何一个。相反,我们需要使用Button的{​​{1}}集合来查找它们。

      • 我们可以设置TabPage或从Controls继承的任何其他属性,但要设置BackColor我们需要转换为Control;我们需要从RadioButton.Checked集合中访问该控件,例如RadioButton

      • 升级到recursive cloning后,您需要使用Controls来包含嵌套控件..

      正如您所看到的那样,它可以完成,但是比编写原始控件需要更多的努力,并且在我们引入隐藏的依赖项时代码感觉有点脆弱:所有这些对克隆名称的引用依靠原始名称!

      最后注意事项:虽然常规专家会被克隆,但NameControls.Find(name, true)容器却没有,即所有datastructureItems,{ <1>}集合等等克隆!

答案 1 :(得分:0)

MyResponse response = new MyResponse();
HttpResponseMessage response = await client.GetAsync(path);
// ok will return success status code, but you will depend on your status to know if it was success or error happened 
if (response.IsSuccessStatusCode)
{
    // Desirialize your result 
    response = await response.Content.ReadAsAsync<MyResponse>();
}
// then get the message, 
if(response.Status)
{
 //it was fine, return something ..
 }
else {
// Error happened, get your error message and disaply it, if you want as viewbag
ViewBag.ErrorMessage = response.Message;
// do something
}

这也可以解决问题:) @TaW已经把解决方案放在那里,但这里有一些复制粘贴代码:)