【问题标题】:Dynamic names for panels面板的动态名称
【发布时间】:2012-10-01 17:41:32
【问题描述】:

我正在开发一个应该与多个用户一起使用的程序。我正在从数据库中获取用户。到目前为止一切顺利...

我正在向表单动态添加一个面板,该面板将保存一些数据。我正在使用这段代码来实现:

string panel_name = "email_in_" + user_credentials[counter_snel][0];
Panel new_user_panel = new Panel();
new_user_panel.AutoSize = true;
new_user_panel.Dock = System.Windows.Forms.DockStyle.Fill;
new_user_panel.Location = new System.Drawing.Point(0, 0);
new_user_panel.Name = panel_name;
new_user_panel.Visible = false;

Label new_item = new Label();
new_item.AutoSize = true;
new_item.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
string new_item_text = string.Format("{0,0}\n{1,0}\n{2,0}", user_credentials[counter_snel][1], user_credentials[counter_snel][2],user_credentials[counter_snel][9]);
new_item.Text = new_item_text;
splitContainer2.panel_name.Controls.Add(new_item);

您可能会注意到,这行代码不起作用:

splitContainer2.panel_name.Controls.Add(new_item);

我怎样才能做到这一点,所以当我想让面板 email_in_1 可见时,我可以使用它,而使 email_in_8 不可见?

### 编辑 1 ###

现在的代码如下所示:

string panel_name = "email_in_" + user_credentials[counter_snel][0];
Panel new_user_panel = new Panel();
new_user_panel.AutoSize = true;
new_user_panel.Dock = System.Windows.Forms.DockStyle.Fill;
new_user_panel.Location = new System.Drawing.Point(0, 0);
new_user_panel.Name = panel_name;
new_user_panel.Visible = true;
user_email_in_panels.Add(new_user_panel);
splitContainer2.Panel1.Controls.Add(new_user_panel);

Label new_item = new Label();
new_item.AutoSize = true;
new_item.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
string new_item_text = string.Format("{0,0}\n{1,0}\n{2,0}", user_credentials[counter_snel][1], user_credentials[counter_snel][2],user_credentials[counter_snel][9]);
new_item.Text = new_item_text;
int aantal_panels = 0;
foreach (Panel panel in user_email_in_panels) {
        aantal_panels++;
}
int counter_1 = 0;
foreach (Panel panel in user_email_in_panels) {
        if(counter_1 == (aantal_panels -1)){
               MessageBox.Show("We are here");
               panel.Controls.Add(new_item);
               splitContainer1.Panel1.Controls.Add(panel);
        }
        counter_1++;
}

但不知何故,我没有看到表单中显示任何标签......我错过了什么吗?显示了带有 We are Here 文本的消息框,所以它出现在 add 语句中......

除了我的第一个问题,我还有另一个问题。我的问题是,我怎样才能使列表的计数器更好?

### 为肖恩·沃恩编辑

我已将其更新为:

public class MyPanelClass {
    public string Name {
        get;
        set;
    }

    public bool Visible {
        get;
        set;
    }

    public string YourLabelsText {
        get;
        set;
    }
}

Label new_item = new Label();
new_item.AutoSize = true;
new_item.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
string new_item_text = string.Format("{0,0}\n{1,0}\n{2,0}", user_credentials[counter_snel][1], user_credentials[counter_snel][2], user_credentials[counter_snel][9]);
new_item.Text = new_item_text;

Panel base_panel = new Panel();    //this is your base panel, you don't need to add this line of code because Visual Studio will do that for you.
List<MyPanelClass> myPanelList = new List<MyPanelClass>();    //this will keep records of all of your panels.

MyPanelClass panel_name = new MyPanelClass();
panel_name.Name = "email_in_" + user_credentials[counter_snel][0]; ;
panel_name.Visible = true;
panel_name.YourLabelsText = string.Format("{0,0}\n{1,0}\n{2,0}", user_credentials[counter_snel][1], user_credentials[counter_snel][2], user_credentials[counter_snel][9]);

//Now add the new created panel to the list.
myPanelList.Add(panel_name);

base_panel.Name = myPanelList[counter_snel].Name;
base_panel.Visible = myPanelList[counter_snel].Visible; //You probably don't need this because base_panel will always be visible
new_item.Text = myPanelList[counter_snel].YourLabelsText;

但我还是什么都没看到... 它在公共空白中执行是否重要???我不这么认为,但它想消除所有的可能性......

【问题讨论】:

  • 您是否尝试过使用RegisterName(panel_name, new_user_panel) 然后使用(Panel)splitContainer1.FindName(panel_name) 来检索它?
  • @Bob.,我明天会看看它,因为如果今天没有时间的话。但感谢您与我们一起思考 ;-)
  • 没问题!我发现如果您要向 WPF 动态添加内容,则必须对其进行注册,以便可以按名称检索它。从看起来你想做的事情来看,你需要的只是一个面板名称的 List,使用 FindName() 检索它们,然后将它们全部设置为 Visiblity.Collapsed,并将你想要的面板设置为 Visiblity。可见。
  • @Bob。你可以在答案中设置它吗?这样我就可以明白你的意思了?

标签: c# winforms dynamic label panel


【解决方案1】:

使用List 来跟踪所有面板。

List<Panel> myPanels = new List<Panel>();

当您需要添加面板时,请执行以下操作:

mypanels.Add(yourPanel);

现在,对于另一个问题,创建一个这样的函数:

private void HideAllOtherPanels(List<Panel> panelList, Int index /*the index of the panel you want to show*/)
{
    foreach(Panel panel in panelList)
        if(panel.Visible) panel.Hide();

    panelList[index].Show();
}

我看到您正在创建很多新面板。我的建议是,不要那样做,你会给系统带来很多负担。

改为上课。

public class MyPanelClass
{
    public string Name
    {
        get; set;
    }

    public bool Visible
    {
        get; set;
    }

    public string YourLabelsText
    {
        get; set;
    }
}

创建类后,在您的表单上创建一个 base_panel,它将根据您的意图更改其内容。 然后,您需要做的就是更改面板的内容,而不是创建一个新的面板。将其他面板数据存储在 List&lt;MyPanelClass&gt; 中。

所以你会这样做:

Panel base_panel = new Panel();    //this is your base panel, you don't need to add this line of code because Visual Studio will do that for you.
List<MyPanelClass> myPanelList = new List<MyPanelClass>();    //this will keep records of all of your panels.

MyPanelClass panel_name = new MyClassPanel();
panel_name.Name = "email_in_" + user_credentials[counter_snel][0];;
panel_name.Visible = false;
panel_name.YourLabelsText = string.Format("{0,0}\n{1,0}\n{2,0}", user_credentials[counter_snel][1], user_credentials[counter_snel][2],user_credentials[counter_snel][9]);

//Now add the new created panel to the list.
myPanelList.Add(panel_name);

现在,当您需要激活存储的面板时,只需执行以下操作:

base_panel.Name = myPanelList[yourPanelsIndex].Name;
base_panel.Visible = myPanelList[yourPanelsIndex].Visible; //You probably don't need this because base_panel will always be visible
yourLabel.Text = myPanelList[yourPanelsIndex].YourLabelsText;

这段代码在机器上的体积要小得多,也很容易处理。

【讨论】:

  • 我看到你编辑了你的答案,我会看看。但是我已经更新了我的问题,你能看一下吗?因为它看起来正在工作,但我没有看到我期望的输出......
  • 我使用了您答案的更新部分,但仍然没有运气。我再次更新了问题;-)
  • 什么运气不好?具体来说?通过 Dropbox 将您的 C# 项目发送给我,我会看看有什么问题。 @TWCrap
  • 这是项目 zip 的链接...希望您找到问题所在 ;-) scriptsenprogs.nl/upload/WeProgram_Mail.zip
  • @TWCrap,我修复了你的项目。 download :)
【解决方案2】:

我会尝试这样的方法来添加一个项目。

var panel = splitContainer2.Controls.FirstOrDefault(p => p is Panel && ((Panel)p).Name == panel_name);
if(panel != nul) 
{
    panel.Controls.Add(new_item);
}

隐藏给定panel_name的特定面板:

foreach(var control in splitContainer2.Controls)
{
    if(control is Panel)
    {
        ((Panel)control).Visible = ((Panel)control).Name == panel_name;
    }
}

【讨论】:

  • 上面发布的第二个代码块将隐藏splitContainer2 中名称与panel_name var 的值不匹配的所有面板。你在上面说:隐藏给定panel_name的特定面板。这是预期的行为吗?
  • @LuisQuijada,隐藏还是不隐藏,这不是现在的问题,但你是对的。
猜你喜欢
  • 2013-11-14
  • 2010-12-10
  • 2011-05-27
  • 2017-09-30
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多