跨多个控件共享事件处理程序

dav*_*oxy 5 c# optimization button event-handling winforms

在用C#编写的Windows窗体应用程序中,我有一堆按钮.当用户的鼠标悬停在按钮上时,我希望按钮的边框发生变化.

目前我有以下多个实例(每个按钮的副本):

private void btnStopServer_MouseEnter(object sender, EventArgs e)
{
    oldColor = btnStopServer.FlatAppearance.BorderColor;
    btnStopServer.FlatAppearance.BorderColor = mouseOverColor;
}

private void btnStopServer_MouseLeave(object sender, EventArgs e)
{
    btnStopServer.FlatAppearance.BorderColor = oldColor;
}
Run Code Online (Sandbox Code Playgroud)

由于我有很多按钮,更改按钮边框颜色的代码占用了大量空间.

有没有更简单的方法可以做到这一点?

Sep*_*ter 5

您应该将单个MouseEnterMouseLeave每个需要此功能的控件连接起来(而不是为每个控件编写每个方法的新版本).假设您正在使用Visual Studio,可以通过在每个Button的属性窗格中更改事件的目标方法名称来完成此操作.如果您首先编写以下代码,则此方法将显示在属性MouseEnterMouseLeave事件的下拉列表中.

上面的代码就需要检查哪些按钮从该事件被触发,如下所示:

private void btnWithHoverBorder_MouseEnter(object sender, EventArgs e)
{
    Button eventButton = (Button) sender;
    oldColor = eventButton.FlatAppearance.BorderColor;
    eventButton.FlatAppearance.BorderColor = mouseOverColor;
}

private void btnWithHoverBorder_MouseLeave(object sender, EventArgs e)
{
    Button eventButton = (Button) sender;
    eventButton.FlatAppearance.BorderColor = oldColor;
}
Run Code Online (Sandbox Code Playgroud)

我认为oldColor是全球性的?如果MouseEnterMouseLeave捕获相应按钮之前触发另一个按钮的事件发生"奇怪"的事情,这可能会失去同步.为了使这个更加健壮,我会考虑将旧颜色存储在Button的.tag属性上,以便它是自包含的.

例如:

private void btnWithHoverBorder_MouseEnter(object sender, EventArgs e)
{
    Button eventButton = (Button) sender;
    eventButton.tag = eventButton.FlatAppearance.BorderColor;
    eventButton.FlatAppearance.BorderColor = mouseOverColor;
}

private void btnWithHoverBorder_MouseLeave(object sender, EventArgs e)
{
    Button eventButton = (Button) sender;
    eventButton.FlatAppearance.BorderColor = (Color)eventButton.tag;
}
Run Code Online (Sandbox Code Playgroud)

(标签基本上是一个钩子,用来标记与控件的特定实例相关的"任何东西",它还没有属性.它的类型Object意味着你可以在那里标记任何东西,但当你从中读取时,你需要把它放回到你放在那里的任何类型.但是因为它是一个Object你可以在那里放任何东西,包括例如包含多个属性的自定义类,或者数组等,如果你需要标记一个控件不止一件事).