C#制作自己的按钮并传递参数

C#制作自己的按钮并传递参数,c#,winforms,custom-controls,C#,Winforms,Custom Controls,我们使用C#form应用程序作为自动化项目的HMI。 在执行此操作时,我们通常使用按钮单击事件。这些事件将布尔值从false更改为true。我的问题从这里开始。 有很多布尔值,如果我一个接一个地添加按钮事件,我将花费很多时间。所以我想做我自己的按钮组件。我将从工具箱中拖放我的按钮,并使用属性窗口将其与布尔值关联。在这样做之后,它将代替我自动完成所有事情。按钮设计对我来说并不重要 例如: //Define Variables public class PLCVars { public bo

我们使用C#form应用程序作为自动化项目的HMI。 在执行此操作时,我们通常使用按钮单击事件。这些事件将布尔值从false更改为true。我的问题从这里开始。 有很多布尔值,如果我一个接一个地添加按钮事件,我将花费很多时间。所以我想做我自己的按钮组件。我将从工具箱中拖放我的按钮,并使用属性窗口将其与布尔值关联。在这样做之后,它将代替我自动完成所有事情。按钮设计对我来说并不重要

例如:

//Define Variables
public class PLCVars
{
    public bool PLCVar1;
    public bool PLCVar2;
    public bool PLCVar3;
    public bool PLCVar4;
    public bool PLCVar5;
    public bool PLCVar6;
    public bool PLCVar7;
    public bool PLCVar8;
}

//(!)I have a PLCVars object defined as PLCVariables
//Button Events 
private void button_JogPLCVar1_MouseDown(object sender, MouseEventArgs e)
{
    PLCVariables.PLCVar1 = true;
}

private void button_JogPLCVar1_MouseUp(object sender, MouseEventArgs e
{
    PLCVariables.PLCVar1 = false;
}
如上面的示例所示,我想将我的按钮组件与plc变量关联起来。它将自动执行所有mouseup和mousedown事件,并更改plc变量的值


当我搜索时,我应该使用自定义控件。但我不知道是否可以将表单变量与自定义控件组件相关联。如果可能,如何进行?

不需要自定义控件。将所有按钮订阅到这两个事件处理程序。您需要做的就是获取
PLCVar
字段名。您可以使用按钮的
标记
属性来实现这一点。将字段名分配给标记
PLCVar1
PLCVar2
等。然后在事件处理程序中获取字段名,并通过反射分配值:

private void button_JogPLCVar_MouseDown(object sender, MouseEventArgs e)
{
    Button button = (Button)sender;
    SetPLCVariable((string)button.Tag, true);
}

private void button_JogPLCVar_MouseUp(object sender, MouseEventArgs e
{
    Button button = (Button)sender;
    SetPLCVariable((string)button.Tag, false);
}

private void SetPLCVariable(string fieldName, bool value)
{
    Type type = typeof(PLCVars);
    FieldInfo fieldInfo = type.GetField(fieldName);
    fieldInfo.SetValue(PLCVariables, true);
}
创建和订阅所有按钮

 panel1.Controls.Clear();

 for (int i = 1; i < 5; i++)
 {
     Button button = new Button();
     button.Name = "Button" + i;
     button.Tag = "PLCVar" + i;
     button.MouseUp += button_JogPLCVar_MouseUp;
     button.MouseDown += button_JogPLCVar_MouseDown;
     panel1.Controls.Add(button);
 }
panel1.Controls.Clear();
对于(int i=1;i<5;i++)
{
按钮按钮=新按钮();
button.Name=“button”+i;
button.Tag=“PLCVar”+i;
button.MouseUp+=button\u JogPLCVar\u MouseUp;
button.MouseDown+=按钮_JogPLCVar _MouseDown;
面板1.控件。添加(按钮);
}

注意:最好使用属性而不是公共字段。对于属性,您需要使用
type.GetProperty
方法。另外,最好使用
FlowLayoutPanel

您只需将一个面板放入表单中,动态创建按钮控件,并将事件附加到创建的控件即可

下面是一个行示例(您必须修改它)

公共类PLCVAR
{
公共布尔PLCVar1;
公共布尔PLCVar2;
公共布尔PLCVar3;
公共布尔PLCVar4;
公共布尔PLCVar5;
公共布尔PLCVar6;
公共布尔PLCVar7;
公共布尔PLCVar8;
公共布尔值[]布尔值()
{
返回新bool[]{PLCVar1,PLCVar2,PLCVar3,PLCVar4,PLCVar5};
}
}
公开作废法()
{
PLCVars v=新的PLCVars();
panel1.控件。清除();
对于(int i=1;i<5;i++)
{
按钮按钮=新按钮();
button.Name=“button”+i;
button.MouseUp+=委托
{
v、 BooleanVars()[i]=false;
};
button.MouseDown+=委托
{
v、 BooleanVars()[i]=true;
};
面板1.控件。添加(按钮);
}
}

更新后,我发现您希望创建一些按钮,并使用这些按钮管理某些对象的属性。这里有更好的解决方案

首先-您应该使用
FlowLayoutPanel
来承载按钮。按钮将动态定位

第二,你不应该使用按钮。使用按钮外观的
复选框
。因为您需要管理布尔属性

Thirs-您应该将
PLCVars
字段更改为属性。因为我们将使用数据绑定。而且它不适用于字段:

public class PLCVars
{
    public bool PLCVar1 { get; set; }
    public bool PLCVar2 { get; set; }
    public bool PLCVar3 { get; set; }
    public bool PLCVar4 { get; set; }
    public bool PLCVar5 { get; set; }
    public bool PLCVar6 { get; set; }
    public bool PLCVar7 { get; set; }
    public bool PLCVar8 { get; set; }
}
现在您不需要任何事件处理程序或自定义按钮。如果您想创建UI来控制
PLCVariables
对象的属性,您只需将复选框添加到面板并将它们绑定到您的对象。简单:

int numberOfVlcVariables = typeof(PLCVars).GetProperties()
      .Count(p => p.Name.StartsWith("PLCVar"));

for(int i = 1; i <= numberOfVlcVariables ; i++)
{
    CheckBox cb = new CheckBox();
    cb.Appearance = Appearance.Button;
    cb.Text = "PLCVar" + i;
    cb.DataBindings.Add("Checked", PLCVariables, "PLCVar" + i);
    flowLayoutPanel1.Controls.Add(cb);
}
结果:


你能澄清一下你问题的某些部分吗。有很多布尔值,如果我一个接一个地添加按钮事件-什么布尔值?它是否像
boolx=false?如何将事件添加到布尔值?给我们看看这个代码。使用属性窗口将其与布尔值关联-这意味着什么?如何将按钮与布尔值关联?我通过添加代码部分编辑了我的问题。我是否应该为所有按钮创建鼠标悬停事件?我将如何关联按钮和这两个事件?好的,我将订阅这两个函数的按钮。我试试看。但特别是我想在C#上创建自己的Autimation库。我会使用很多东西,比如文本框、图片框、radiobutton等等。我应该每次都使用这个方法,还是在我提问时创建自己的dll?哪一个更好?@tebdilikiyafet stackoverflow不是关于编写dll指南。它是用来解决你的工作中的特殊问题的code@tebdilikiyafet我有更好的办法给你。等一下,我会更新答案谢谢你的回答。和Sergey的逻辑一样是的。。。他发帖后看到的。但是我不得不问。。。当您可以只使用委托时,为什么需要创建一个单独的方法并使用反射?它比那个实现更快更干净。你的例子是最好的解决方案。我已经忘记了数据绑定+来自meI的1不希望在for循环中动态添加按钮。我会在需要时手动添加按钮。我会写它的标签。就这样。所以我想我不需要FlowLayoutPanel。我只想简化我的工作。我现在很困惑。你可以这样想,我只需要数字文本框,我不想为所有文本框编写控制函数。
int numberOfVlcVariables = typeof(PLCVars).GetProperties()
      .Count(p => p.Name.StartsWith("PLCVar"));

for(int i = 1; i <= numberOfVlcVariables ; i++)
{
    CheckBox cb = new CheckBox();
    cb.Appearance = Appearance.Button;
    cb.Text = "PLCVar" + i;
    cb.DataBindings.Add("Checked", PLCVariables, "PLCVar" + i);
    flowLayoutPanel1.Controls.Add(cb);
}
propertyGrid1.SelectedObject = PLCVariables;