当选择了一个菜单选项时,我有一个usercontrol加载到winform应用程序中Form1上的面板。 usercontrol具有用于触发打印机选择对话框的按钮,并允许用户为应用程序设置多个打印机。每个按钮配置应用程序中的设置属性以存储打印机。在每个按钮下面都有一个标签,用于显示设置属性中的打印机名称。
我正在使用事件管理来自usercontrol的按钮点击。在settings属性中存储正确的打印机的事件一切都很好。但是,我希望标签在我在打印机对话框中选择后立即显示所选的打印机。它不会显示打印机的更改,直到我离开用户控件并返回。然后它显示每个按钮的正确打印机名称。
我能够写好标签文字。我尝试刷新标签,使标签无效并更新。似乎没什么用。只有导航和返回才会在标签中显示打印机名称。
这是我在Form1上的一个按钮点击处理程序:
private void btnTwoByHalf_Click(object sender, EventArgs e)
{
ucPrinterSetup prn = new ucPrinterSetup();
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
prn.lblTwoByHalf.Text = twoByHalf.Printer;
}
这是我的菜单选项点击处理程序:
private void configurePrintersToolStripMenuItem_Click(object sender, EventArgs e)
{
ClearFrames();
ucPrinterSetup printerSetup = new ucPrinterSetup();
pnlMenu.Controls.Add(printerSetup);
printerSetup.btnTwoByHalfClick += new EventHandler(btnTwoByHalf_Click);
printerSetup.btnFourByOneClick += new EventHandler(btnFourByOne_Click);
printerSetup.btnFourByTwoFiveClick += new EventHandler(btnFourByTwoFive_Click);
printerSetup.btnMiscClick += new EventHandler(btnMisc_Click);
printerSetup.btnDefaultClick += new EventHandler(btnDefault_Click);
printerSetup.btnSecondaryClick += new EventHandler(btnSecondary_Click);
ucConfigurePrinters configurePrinters = new ucConfigurePrinters();
pnlFrame.Controls.Add(configurePrinters);
}
这是来自ucPrinterSetup.cs的按钮点击处理程序:
private void btnTwoByHalf_Click(object sender, EventArgs e)
{
if (btnTwoByHalfClick != null)
btnTwoByHalfClick(sender, e);
}
其他一切都很好。在我选择新打印机之后,它才会更新label.text,直到我离开ucPrinterSetup并返回。
更新1: 我的打印机通过以下方式存储在应用程序设置中:
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
twoByHalf.PropName是我在应用程序的settings属性中预先输入的名称。
然后我将标签文本设置为打印机的名称:
prn.lblTwoByHalf.Text = twoByHalf.Printer;
在应用程序设置中,我将打印机名称预设为:
TwoByHalfPrn - string - User - (no value)
答案 0 :(得分:1)
主要问题似乎是您在控件上设置标签而不是您正在显示的控件。
当您的点击事件(btnTwoByHalf_Click
)被调用时,您应该使用
当前显示的用户控件,而是使用ucPrinterSetup prn = new ucPrinterSetup();
这与显示的控件不同,而是一个全新的控件,因此当您更改prn
中的标签时,您会在不可见的控件中更改标签,原始控件将保持不变。
我可以看到4种获取原始控件的方法:
1。 你可以从菜单中获得它。如果您在菜单中只有一个此控件类型的实例,则可以使用类似的东西(在我的代码中没有错误处理):
ucPrinterSetup prn = pnlMenu.Controls.OfType<ucPrinterSetup>().First();
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
prn.lblTwoByHalf.Text = twoByHalf.Printer;
或者,如果您确实有多个名称,则可以为控件指定不同的名称并使用pnlMenu.Controls.Find("YourControlNameGoesHere", false).First();
2。
您可以在活动中从sender
财产获取。发件人是控件中的按钮,因此假设按钮直接位于控件中,按钮的父级将成为控件:
ucPrinterSetup prn = (ucPrinterSetup)((Control)sender).Parent);
如果按钮没有直接坐在控件中(例如,它可能位于控件中的面板中),那么您可能需要更多地启动链,您可以在事件条目中放置断点并检查发件人。
3。 第三种方式可能是最好的,但它需要你改变你的设计。您似乎每次单击菜单时反复创建控件。也许这是一个很好的理由,但假设它没有真正的理由,那么在你启动时创建一次用户控件可能会更好,只需将原来的控件切换进去。然后你可以把你的控件放在一个类变量中并在事件中使用它。
4。 为了完整起见,您还可以为事件使用lambda / anonymous方法,并在注册事件时捕获控件。 如果您这样做,那么在注册事件的方法中,将注册码替换为如下所示:
printerSetup.btnTwoByHalfClick += (sender, e) => btnTwoByHalf_Click(printerSetup );
然后将您的事件方法签名和代码更改为:
private void btnTwoByHalf_Click(ucPrinterSetup prn)
{
twoByHalf.PropName = "TwoByHalfPrn";
twoByHalf.SetPrinter(twoByHalf.PropName);
prn.lblTwoByHalf.Text = twoByHalf.Printer;
}
这可能是最容易使用的代码,并且不易出错,但请注意,如果您稍后需要取消注册该事件,则可能会非常棘手。