C# 是否可以有多个控制按钮。标记

C# 是否可以有多个控制按钮。标记,c#,winforms,C#,Winforms,此应用程序提示您打开文件夹。然后应用程序查看文件夹中的所有文件,并为每个(.wav)文件生成一个按钮。我当时打算在按下按钮时播放(.wav)文件 因为它是我动态创建的按钮。我使用button.Tag发送按钮编号,但我希望发送另一个保存wav文件完整路径的对象。我已经添加了它,但是我知道你不能像我那样添加两个按钮.Tag。所以我的问题是如何实现这一点 public partial class Form1 : Form { public SoundPlayer Sound1; pub

此应用程序提示您打开文件夹。然后应用程序查看文件夹中的所有文件,并为每个(.wav)文件生成一个按钮。我当时打算在按下按钮时播放(.wav)文件

因为它是我动态创建的按钮。我使用
button.Tag
发送按钮编号,但我希望发送另一个保存wav文件完整路径的对象。我已经添加了它,但是我知道你不能像我那样添加两个
按钮.Tag
。所以我的问题是如何实现这一点

public partial class Form1 : Form
{
    public SoundPlayer Sound1;
    public static int btnCount = 0;

    public Form1()
    {
        InitializeComponent();
        SetFolderPath();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    public void addDynamicButton(string folder, string fileName)
    {
        btnCount++;
        string soundfilepath = folder + "\\" + fileName + ".wav";

        Button button = new Button();
        button.Location = new Point(20, 30 * btnCount + 10);
        button.Size = new Size(300, 23);

        button.Text = fileName;
        button.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
        button.UseVisualStyleBackColor = true;

        button.Click += new EventHandler(btnDynClickEvent);
        button.Tag = btnCount;
        button.Tag = soundfilepath;
        this.Controls.Add(button);

    }

    void btnDynClickEvent(object sender, EventArgs e)
    {
        Button button = sender as Button;
        if (button != null)
        {

            switch ((int)button.Tag)
            {
                case 1:
                    Sound1 = new SoundPlayer((string)button.Tag);
                Sound1.Play();
                break;

            }
        }
    }

    public void SetFolderPath()
    {

        FolderBrowserDialog folder = new FolderBrowserDialog();

        folder.Description = "Select the sound file Folder";

        if (textBox1.Text.Length > 2)
        {
            folder.SelectedPath = textBox1.Text;
        }

        else
        {
            folder.SelectedPath = @"C:\";
        }

        if (folder.ShowDialog() == DialogResult.OK)
        {
            textBox1.Text = folder.SelectedPath;

            string[] files = Directory.GetFiles(folder.SelectedPath, "*.wav", SearchOption.AllDirectories);
            int count = files.Length;

            richTextBox1.Text = count.ToString() + " Files Found";

            foreach (string file in files)
            {
                string fileName = Path.GetFileNameWithoutExtension(file);
                addDynamicButton(folder.SelectedPath, fileName);
            }
        }
    }


    private void btnOpenFolder(object sender, EventArgs e)
    {
        SetFolderPath();
    }


}

实际上不可能有多个标记,但可以使用
列表
列表
列表
)或数组作为
标记

您还可以创建自己的类,以包含所有需要的信息,最好是:

class MyTagInfo
{
    public int Num;
    public string Text;
    public bool SomeMoreInfo;
}
使用方法:

myControl.Tag = new MyTagInfo { Num = 0, Text = "Hello World!" };

您可以将列表存储到标记属性中,该属性允许您在其中存储多个对象

button.Tag = new List<object>();
(List<object> button.Tag).Add(btnCount);
(List<object> button.Tag).Add(soundfilepath);
button.Tag=新列表();
(列表按钮.Tag).添加(btnCount);
添加(声音文件路径);

我建议在
标记中存储一个专用对象
属性:

class WaveDetailTag {

    public FileInfo WaveFile {get; set;}
    public int ButtonId {get; set;}

}
实施:

// ...
button.Tag = new WaveDetailTag() { 
    WaveFile = new FileInfo(soundfilepath), 
    ButtonId = btnCount 
};
// ...
更新
开关箱中使用

    Button button = sender as Button;
    if (button != null)
    {
        var waveDetail = (WaveDetailTag)button.Tag;
        switch (waveDetail.ButtonId)
        {
            case 1:
                Sound1 = new SoundPlayer(waveDetail.WaveFile.FullName);
                Sound1.Play();
                break;
        }
    }

使用自定义类并将其存储在
标记
属性中,类似于:

public class WaveButton
{
    public int Number { get; set; }
    public string WaveFilePath { get; set; }
}

.....


button.Tag = new WaveButton() { Number = n, WaveFilePath = path }

你应该像这样设置你的标签

button.Tag= new {Count = btnCount, FileName=soundFfilepath);//anonymouse type
当您想要检索您的值时,可以使用dynamic

int count=((dynamic)button.Tag).Count;
string filename=((dynamic)button.Tag).FileName;


还可以为第二个解决方案创建新方法

object GetValueByProperty(object obj,string propName)
{
 return   obj.GetType().GetProperty(propName).GetValue(obj, null);
}
调用

int count=(int) GetValueByProperty(button.Tag,"Count");
string filename=GetValueByProperty(button.Tag,"FileName");.ToString();

我知道为时已晚,但我想出了一个简单的方法。 只需连接字符串,如
string join=string.join(“,”firstString,secondString);
Tag=join
在使用它之前,把它分成两个字符串,就像这样

string[] split = join.Split(',');
        string title = split[1];
        string link = split[0];
并根据需要使用字符串标题和字符串链接。(Y) 我不知道这是否是一个好的做法,但我正在使用它,它的工作完美

我是c#的新手


声明一个类ExtraButtonInfo,该类保存每个按钮所需的所有额外信息,并将ExtraButtonInfo的实例分配给每个按钮的Tag属性。类型为
object
named
Add
或类似内容的
标记的未知方法或扩展。您应该将
标记
强制转换为
列表
,以便将其用作列表。标记是
对象
,必须在添加任何内容之前强制转换,
列表
(或任何列表)是一个非常糟糕的主意。假设
[0]
是一个
int
[1]
是一个
字符串
会留下很多错误的空间-更不用说从
对象
强制转换项目了。我同意在这种情况下,特定的类更整洁。@IAbstract如何在交换机案例中使用它?谢谢你的帮助。
string[] split = join.Split(',');
        string title = split[1];
        string link = split[0];