首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Winforms控件

Winforms控件
EN

Stack Overflow用户
提问于 2013-07-26 16:55:37
回答 2查看 537关注 0票数 3

我有一个按钮,我一直在用它作为组合框旁边的一个小选择按钮。当我点击按钮时,我会打开一个更大的完整列表。这方面的事情运行得很好,我对此没有问题。

我的问题在于,当有人对我说,你能把你挑选的丑陋的图标改成我的漂亮图标吗?

我搞砸了,我有成百上千个这样的按钮在很多表单上。因此,我想我将创建一个名为PickButton的自定义控件(这是一个标准按钮和一堆默认属性集),并将它们放在窗体中的任何地方。在PickButton自定义控件的代码中,我设置了一些属性和客户漂亮图标的图像。

所以我把PickButton从我的工具箱放到表单上,到目前为止,一切看起来都很好,我感觉有点聪明。现在,我想我应该改回我漂亮的图标,而不是客户选择的那个糟糕的图标,并更改PickButton自定义控件中的代码。但我无法摆脱客户图标,因为PickButton运行时的代码发生在具有客户图标的设计器文件中的代码之前。

因此,我的目标是拥有一个PickButton控件,并且能够在一个地方更改图标和其他属性,并且所有属性都将在创建控件实例并在窗体上显示时设置。

我是不是不够聪明,以错误的方式去完成任务?

这是我的PickButton自定义控件类

代码语言:javascript
复制
public class PickButton : Button
{

    public PickButton()
    {
        InitialiseButton();
    }

    internal void InitialiseButton()
    {
        this.ImageAlign = ContentAlignment.MiddleCenter;
        this.Image = WindowsFormsApplication1.Properties.Resources.Cancel.ToBitmap();
        this.Size = new Size( 28, 28 );
        this.Dock = DockStyle.Fill;
        this.Margin = new Padding( 0, 2, 2, 0 );
        this.Text = string.Empty;
    }
}

现在我将一个放在窗体上,设计器中的代码如下所示

代码语言:javascript
复制
 // 
        // pickButton1
        // 
        this.pickButton1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.pickButton1.Image = ((System.Drawing.Image)(resources.GetObject("pickButton1.Image")));
        this.pickButton1.Location = new System.Drawing.Point(0, 0);
        this.pickButton1.Margin = new System.Windows.Forms.Padding(0, 2, 2, 0);
        this.pickButton1.Name = "pickButton1";
        this.pickButton1.Size = new System.Drawing.Size(284, 262);
        this.pickButton1.TabIndex = 0;
        this.pickButton1.Text = "pickButton1";
        this.pickButton1.UseVisualStyleBackColor = true;

现在,我想要更改图像,因此我更改了PickButton代码以使用不同的图标

this.Image = WindowsFormsApplication1.Properties.Resources.Browse.ToBitmap();

运行应用程序,由于设计器文件中的这行代码,第一个图标仍然是显示的图标

代码语言:javascript
复制
        this.pickButton1.Image = ((System.Drawing.Image)(resources.GetObject("pickButton1.Image")));
EN

回答 2

Stack Overflow用户

发布于 2013-10-24 21:54:43

在一个地方设置所有属性的概念是一个好主意,只是没有很好地实现。我会让这个类继承自UserControl而不是Button。通过将其设置为UserControl,您可以使用设计器设置所需的所有属性,如按钮的默认图像。在设计器中进行设置,然后只需将UserControl从工具箱拖放到窗体上。如果您只使用带有combobox的"PickButton“控件,我也会将combobox放在UserControl上。如果您将来想要更改按钮图像(或任何其他属性),您将能够在ctlPickButton中更改它,这将传播对整个项目中使用的所有实例的更改。

ctlPickButton:

代码语言:javascript
复制
public partial class ctlPickButton : UserControl
{
    public event EventHandler pickButtonClicked;

    public ctlPickButton()
    {
        InitializeComponent();
    }

    //Allows buttons image to be set in code if necessary
    public Image Image
    {
        get
        {
            return button1.Image;
        }
        set
        {
            if (Image != null)
            {
                button1.Image = value;
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (pickButtonClicked != null)
        {
            pickButtonClicked(sender, e);
        }
    }
}

演示表单:

代码语言:javascript
复制
    public Form1()
    {
        InitializeComponent();

        ctlPickButton1.pickButtonClicked += new EventHandler(ctlPickButton1_pickButtonClicked);
        ctlPickButton2.pickButtonClicked += new EventHandler(ctlPickButton2_pickButtonClicked);
    }

    void ctlPickButton2_pickButtonClicked(object sender, EventArgs e)
    {
        if (comboBox2.SelectedItem != null)
        {
            MessageBox.Show(comboBox2.SelectedItem.ToString());
        }
    }

    void ctlPickButton1_pickButtonClicked(object sender, EventArgs e)
    {
        if (comboBox1.SelectedItem != null)
        {
            MessageBox.Show(comboBox1.SelectedItem.ToString());
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        comboBox1.Items.Add("French");
        comboBox1.Items.Add("Spanish");
        comboBox1.Items.Add("English");
        comboBox1.Items.Add("German");

        comboBox2.Items.Add("Pizza");
        comboBox2.Items.Add("Hamburger");
        comboBox2.Items.Add("Potato");
        comboBox2.Items.Add("Chicken");

        //Shows how the default image set in the designer can be overwritten for a 
        //specific instance using the "Image" property
        ctlPickButton2.Image = Testbed.Properties.Resources.searchIcon2;
    }
}

设计器中的ctlPickButton图像

票数 0
EN

Stack Overflow用户

发布于 2013-10-25 17:28:49

我想我已经找到了一个简单、干净的解决方案:

CustomButton类(继承自System.Windows.Forms.Button)中,重写Refresh()方法,并将按钮的图像设置为您希望看到的图像:

代码语言:javascript
复制
public class CustomButton : Button
{
  public override void Refresh()
  {
    Image = MyResources.HappyFace;
  }
}

在保存CustomButton实例的表单中,只需在InitializeComponent()之后的构造函数中调用customButton.Refresh()

代码语言:javascript
复制
public partial class MainForm : Form
{
  public MainForm()
  {
    InitializeComponent();

    customButton.Refresh();
  }
}

我放了一个demo application up on Github

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17877046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档