C# 是否可以将同一个Windows窗体控件实例添加到多个容器中? 我正在努力实现的目标:
我有一个有多个页面的向导。在每个页面上,我都需要一个ToolStripDropDownButton,每个都有完全相同的功能和UI。在显示任何页面之前,将创建整个向导和所有页面。ToolStripDropDownButton显示在页面边界内。当用户在一个页面上更改ToolStripDropDownButton的值时,应该在其他页面上更新它 我试图避免的替代解决方案是: 在每个页面上都有一个单独的控件实例,该实例订阅了当任何其他控件的值更改时触发的事件。除了它的复杂性之外,这个解决方案没有什么错 我所尝试的: 我创建了ToolStripDropDownButton作为向导页面类的静态成员,在第一次请求时对其进行实例化,并在创建页面时向每个页面添加相同的对象。这导致ToolStripDropDownButton没有出现在任何页面上(可能是因为我将它添加到了多个控件中,Winforms不知道如何处理它)C# 是否可以将同一个Windows窗体控件实例添加到多个容器中? 我正在努力实现的目标:,c#,winforms,C#,Winforms,我有一个有多个页面的向导。在每个页面上,我都需要一个ToolStripDropDownButton,每个都有完全相同的功能和UI。在显示任何页面之前,将创建整个向导和所有页面。ToolStripDropDownButton显示在页面边界内。当用户在一个页面上更改ToolStripDropDownButton的值时,应该在其他页面上更新它 我试图避免的替代解决方案是: 在每个页面上都有一个单独的控件实例,该实例订阅了当任何其他控件的值更改时触发的事件。除了它的复杂性之外,这个解决方案没有什么错 我
如果无法将同一个控件实例添加到多个容器中,是否有比引发和订阅事件更好的方法来完成此任务?例如,您可以使用一些数据对象扩展
ToolStripDropDownButton
,然后使用不同的父对象创建多个ToolStripDropDownButton
实例,然后将它们连接到同一数据对象,并使用该数据对象使ToolStripDropDownButton
实例保持同步,例如:
public class MyToolStripDropDownButton : ToolStripDropDownButton
{
public MyData Data { get; private set; }
public MyToolStripDropDownButton():base()
{
this.Text = "Options";
}
public void Initialize(MyData data)
{
this.Data = data;
this.Data.ElementsToNotify.Add(this);
foreach (string option in this.Data.Options.Keys)
{
ToolStripMenuItem item = new ToolStripMenuItem(option);
item.CheckOnClick = true;
item.CheckedChanged += new EventHandler(item_CheckedChanged);
this.DropDownItems.Add(item);
}
}
void item_CheckedChanged(object sender, EventArgs e)
{
ToolStripMenuItem item = (ToolStripMenuItem)sender;
this.Data.OnSelectOption(item.Text, item.Checked);
}
}
public class MyData
{
public List<MyToolStripDropDownButton> ElementsToNotify { get; private set; }
public Dictionary<string, bool> Options { get; private set; }
public MyData()
{
this.Options = new Dictionary<string, bool>();
this.ElementsToNotify = new List<MyToolStripDropDownButton>();
}
public void OnSelectOption(string option, bool isChecked)
{
Options[option]=isChecked;
foreach (MyToolStripDropDownButton btn in ElementsToNotify)
{
foreach(ToolStripMenuItem item in btn.DropDownItems.OfType<ToolStripMenuItem>())
{
item.Checked = Options[item.Text];
}
}
}
}
您无法执行所需的操作,控件只能有一个父控件
解决方法是:在每个页面的VisibleChanged事件中将控件从一个页面移动到下一个页面。从用户的角度来看,该控件存在于每个页面上,但实际上,当它变为可见时,它将被移动到“当前”页面。您不能将一个控件添加到多个容器中。您不能,您只能通知您的朋友也要更改。为什么要进行否决投票?这是我第一次发布问题,我想知道下一次如何做得更好。我认为这个问题很好,也许可以粘贴一些有效的解决方案代码,但您不喜欢它,因此,我们可以提示如何改进它,并提供一个片段,显示您如何尝试将同一控件添加到多个容器中,以及显示了哪些错误。No。一个控件只能有一个父控件。解决方法是:在每个页面的VisibleChanged事件中将控件从一个页面移动到下一个页面。从用户的角度来看,控件存在于每个页面上,但实际上,当控件变为可见时,它将被移动到“当前”页面。
MyData data = new MyData();
data.Options.Add("A", false);
data.Options.Add("B", false);
data.Options.Add("C", false);
MyToolStripDropDownButton mb1 = new MyToolStripDropDownButton();
mb1.Initialize(data);
MyToolStripDropDownButton mb2 = new MyToolStripDropDownButton();
mb2.Initialize(data);
toolStrip1.Items.Add(mb1);
toolStrip2.Items.Add(mb2);