在我用C#编写的WinForms应用程序中,一个Form上有一个Button,需要稍微改变第二个Form的外观(只需更改Button上的Text)。
我已经设法做到了这一点,但代码非常长,我相信必须有一种更简洁的方法来实现同样的目标。
这是我的表单上的按钮frmConflicts的代码,以及它如何更改窗体frmAdmin上的按钮btnAddCase上的文本(工作,但似乎太长) -
private void btnNoConflicts_Click(object sender, EventArgs e)
{
try
{
foreach (Form f in Application.OpenForms)
{
if (f.Name == "frmAdmin")
{
frmAdmin a = (frmAdmin)f;
a.conflictsClear = true;
foreach (Control ctrl in a.Controls)
{
if (ctrl.Name == "panAdmin")
{
foreach (Control ctrl2 in ctrl.Controls)
{
if (ctrl2.Name == "tabControlAdmin")
{
TabControl tab = (TabControl)ctrl2;
foreach(TabPage page in tab.TabPages)
{
if (page.Name == "pageNewCase")
{
foreach (Control ctrl3 in page.Controls)
{
if (ctrl3.Name == "panCaseDetails")
{
foreach (Control ctrl4 in ctrl3.Controls)
{
if (ctrl4.Name == "btnAddCase")
{
ctrl4.Text = "Add Case";
}
}
}
}
}
}
}
}
}
}
}
}
this.Close();
}
catch (Exception eX)
{
MessageBox.Show("frmConflicts: btnNoConflicts()" + Environment.NewLine + eX.Message);
}
任何有助于显着减少代码量的帮助都会非常受欢迎,因为我需要在我的应用程序的其他地方进行类似的交互。
答案 0 :(得分:5)
如果您的按钮是通过设计师添加的,并且未动态创建,则解决方案很简单:在frmAdmin
内添加方法
public void ChangeCaption(string caption)
{
btnAddCase.Text = "Add case";
}
然后
var frmAdmin = Application.OpenForms.OfType<Form>().FirstOrDefault(x => x.GetType() == typeof(frmAdmin));
if (frmAdmin != null)
{
frmAdmin.ChangeCaption("Add case");
}
答案 1 :(得分:1)
我认为这对你很有帮助
foreach (Form f in Application.OpenForms)
{
var controls =this.Controls.Find("btnAddCase", true);
if(controls!=null)
foreach(var control in controls)
{
control.Text="Add case";
}
}
答案 2 :(得分:1)
如果第二个的出现需要先改变,你应该用另一种方式来解决这个问题。
最好的是,您需要更改的按钮应该打开以捕获表单2打开的事件,然后应用所需的更改。
在您声明按钮的位置,您应该为其分配一个侦听器,该侦听器将捕获Form2开头,然后应用操作。
所以在方法private void btnNoConflicts_Click(object sender, EventArgs e)
中你应该触发该按钮的事件来捕获而不是搜索它。
答案 3 :(得分:0)
您可以使用LINQ + ControlCollection.Find
:
Control btnAddCase = Application.OpenForms.Cast<Form>()
.Where(f => f.Name == "frmAdmin")
.SelectMany(f => f.Controls.Find("btnAddCase", true)) // true means recursive
.FirstOrDefault();
if(btnAddCase != null)
btnAddCase.Text = "Add Case";
答案 4 :(得分:0)
您可以创建公共属性并从表单订阅PropertyChanged事件,您需要具有公共变量的类来扩展INotifyPropertyChanged。
//Your class
public class ButtonText : INotifyPropertyChanged
{
private string _buttonText;
public string ButtonValue
{
get{ return _buttonText; }
set
{
//Sets the value of _buttonText to the value passed in an argument
_buttonText = value;
RaisePropertyChanged("ButtonValue");
}
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
在您的表单类中,您将绑定到ButtonText类的属性ButtonValue属性,如下所示:
ButtonText buttonObj = new ButtonText();
//Property field to bind, object to bind, property to bind
btnAddCase.DataBindings.Add("Text", buttonObj,"ButtonValue");
buttonObj.ButtonText = "Your text to bind.";
因为btnAddCase.Text属性绑定到ButtonText类的ButtonValue属性,所以btnAddCase.Text属性将始终反映ButtonText.ButtonValue属性的值,它也是双向绑定。