C# String als Variablenname?

Atreju93

Lieutenant
Dabei seit
Nov. 2010
Beiträge
586
Hallo zusammen

Ich habe folgendes Problem: Ich habe eine Form, bei der ich dynamisch zur Laufzeit durch einen Buttonklick neue Buttons zur Form hinzufüge. Dies ist an für sich auch kein Problem - ich scheitere jedoch daran, wenn mit einem Klick auf den gleichen button jedes mal ein Zusätzlicher Button zur Form hinzugefügt werden soll.

Ich möchte deshalb z.b. die Buttons: btnFav1, btnFav2 usw.. nennen - dazu müsste ich im Namen des Button einen Counter hochzählen lassen.

Doch wie nehme ich einen int oder in meinem Falle einen string (kombiniert aus einem String und einem counter (int) ) als name für den Button?

Ich möchte z.b. button (strButtonName) anstelle von Button btnFav1 stehen haben.. doch dies geht nicht.

hier mein Code:

Code:
private void AddButton()
        {
            ntFavcount++;
            string strButtonname = "btnFav" + Convert.ToString(ntFavcount);
            Button btnFav1 = new Button();
            btnFav1.Width = 150; 
            btnFav1.Height = 25; 
            btnFav1.Left = button_zurueck.Left ; 
            btnFav1.Top = button_zurueck.Top + 42; 
            btnFav1.Text = "Klick mich"; 
            splitContainer1.Panel1.Controls.Add(btnFav1); 
        }
Kann mir da jemand weiterhelfen?
 

evilbaschdi

Lt. Commander
Dabei seit
Aug. 2011
Beiträge
1.928
btnFav1.Name
 

PEASANT KING

Lt. Commander
Dabei seit
Okt. 2008
Beiträge
2.035
Edit: schließe mich meinem Vorredner an.
 

wahli

Rear Admiral
Dabei seit
Feb. 2010
Beiträge
5.906
Ich weiß nicht, ob es geht, aber kannst du die dynamischen Buttons nicht in einem Array halten?
 

character

Lt. Commander
Dabei seit
Juli 2008
Beiträge
1.615
Ich weiss nicht, ob das in C# ohne weiteres funktionieren wuerde, aber generell gilt: Sowas macht man nicht. Unabhaengig von der Programmiersprache ist das ist ein Unding.

Wenn du auf die Buttons spaeter zugreifen willst (was vermutlich sowieso irgendwie ueber das Panel funktionieren wird), dann kannst du sie in eine Map packen. Generell weiss ich aber nicht, wozu das gut sein sollte. Der Variablenname des Buttons duerfte jedenfalls in jedem Fall irrelevant sein.
 

Atreju93

Lieutenant
Ersteller dieses Themas
Dabei seit
Nov. 2010
Beiträge
586
Hmm.. in ein Array packen?

Ich habe C# nie glernt - ich habe mir die Grundlagen selbst beigebracht.. deshalb wohl meine unkonventionellen Lösungen..

Grundsätzlich programmiere ich einen kleinen Browser - und möchte eine Favoritenliste machen. Dazu möchte ich bei Klick auf einen "Favoriten Hinzufügen" button einen Button erstellen - der dann bei Klick auf diesem diese Seite lädt..

wenn ihr eine Bessere Lösung habt - ich bin offen :-)
 

soul0ry

Lt. Junior Grade
Dabei seit
Mai 2007
Beiträge
399
wenn es eine unbestimmte anzahl von buttons seien soll, dann eignet sich am besten ein HashSet oder eine (Linked)-List oder ein
Dictionary (je nach dem ob du noch eine 2. variable zu dem button speichern willst oder es geordnet seien soll)

z.B. beim HashSet:
Code:
System.Collections.Generic.HashSet<System.Windows.Forms.Button> buttons = new System.Collections.Generic.HashSet<System.Windows.Forms.Button>();
buttons.Add(new System.Windows.Forms.Button());
 
Zuletzt bearbeitet:

Apllepie

Ensign
Dabei seit
Okt. 2007
Beiträge
153
du musst die buttons nicht in einem array speichern,
ein problem das ich hier sehe ist, dass du erstens den dynamischen buttons keine events zuordnest und zweitens wenn du den gleichen button 2 mal drückst, wird der button auch immer wieder an der gleichen stelle platziert ^^

außer du hast eine private variable button button_zurück und würdest die bei addbutton immer mit butfav1 überschreiben ^^ dann dürfte das gehen
 

soul0ry

Lt. Junior Grade
Dabei seit
Mai 2007
Beiträge
399
@Freeman4gu
Doch er muss sie speichern, ich nehme mal an, die Buttons sollen nach einem Neustart des Browsers wieder da sein, dafür muss man aber wissen welche Buttons man denn speichern will.
 

Atreju93

Lieutenant
Ersteller dieses Themas
Dabei seit
Nov. 2010
Beiträge
586
Hmm..

Also Ich habe es mittlerweile umgangen - so funktioniert es nicht schlecht.

Code:
        private void AddButton()
        {
            ntFavcount++;
            ntAbstand += 160;
            string strButtonname = "btnFav" + Convert.ToString(ntFavcount);
            Button btnFav1 = new Button();
            btnFav1.Width = 150; 
            btnFav1.Height = 25; 
            btnFav1.Left = button_zurueck.Left + ntAbstand ; 
            btnFav1.Top = button_zurueck.Top + 42; 
            btnFav1.Text = "Klick mich"; 
            splitContainer1.Panel1.Controls.Add(btnFav1);
            btnFav1.Name = strButtonname;
        }
Aber ich habe das Gefühl, dass diese Lösung sehr unsauber ist..$

EDIT:

Das ist eine Murkslösung - schon das Ansprechen und erstellen von Eventhandler wird mit den variablen Namen mühsam..
 
Zuletzt bearbeitet:

holy

Lieutenant
Dabei seit
Aug. 2008
Beiträge
533
So unglaublich gruselig, was hier manche schreiben ^^
Hier ein Beispiel, wie man es machen kann. Im Anhang gibts das entsprechende Projekt inkl. dem Form.

Have fun.

Code:
namespace WindowsFormsApplication1
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Windows.Forms;
    using System.Xml.Serialization;

    public partial class Form1 : Form
    {
        #region Constants and Fields

        /// <summary>
        /// Eine Liste mit Bookmarks
        /// </summary>
        private readonly List<Bookmark> _bookmarks;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Ctor
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            this.Closing += OnApplicationClosing;

            // Bookmarks werden im gleichen Verzeichnis wie das Assembly gespeichert....
            string path = string.Format( @"{0}\bookmarks.xml", Environment.CurrentDirectory );
            if ( File.Exists( path ) )
            {
                // Bookmarks laden...
                XmlSerializer s = new XmlSerializer( typeof( List<Bookmark> ) );
                var stream = File.Open( path, FileMode.Open, FileAccess.Read );
                _bookmarks = (List<Bookmark>)s.Deserialize( stream );
                stream.Close();
                stream.Dispose();

                foreach ( var bookmark in _bookmarks )
                {
                    ToolStripItem item = new ToolStripButton( bookmark.Title, null, OnNavigateToBookmark );
                    favoritesToolStrip.DropDownItems.Add( item );
                }
            }
            else
            {
                // falls die Bookmarks-Datei nicht existiert, muss die Liste initialisiert werden.
                _bookmarks = new List<Bookmark>();
            }
        }

        #endregion

        #region Methods

        // Wird aufgerufen, wenn ein Bookmark hinzugefügt werden soll. (Add Bookmark im Menü)
        private void OnAddBookmark( object sender, MouseEventArgs e )
        {
            if ( e.Button != MouseButtons.Left )
            {
                return;
            }

            Bookmark bookmark = new Bookmark { Title = webBrowser.DocumentTitle, URL = webBrowser.Url.AbsoluteUri };
            _bookmarks.Add( bookmark );
            ToolStripItem item = new ToolStripButton( bookmark.Title, null, OnNavigateToBookmark );
            favoritesToolStrip.DropDownItems.Add( item );
        }

        // Sobald in der AddressBar Enter gedrückt wird, navigiert der Browser dort hin..
        private void OnAddressBarKeyDown( object sender, KeyEventArgs e )
        {
            if ( e.KeyCode != Keys.Enter )
            {
                return;
            }

            webBrowser.Navigate( addressBar.Text );
        }

        // Bookmarks speichern, bevor die Anwendung beendet wird..
        private void OnApplicationClosing( object sender, CancelEventArgs e )
        {
            if ( _bookmarks == null || _bookmarks.Count == 0 )
            {
                return;
            }

            try
            {
                XmlSerializer s = new XmlSerializer( typeof( List<Bookmark> ) );
                string path = string.Format( @"{0}\bookmarks.xml", Environment.CurrentDirectory );
                var stream = File.Open( path, FileMode.Create, FileAccess.ReadWrite );
                s.Serialize( stream, _bookmarks );
                stream.Close();
                stream.Dispose();
            }
            catch ( Exception ex )
            {
                // Error handling..
            }
        }

        // Menü-Eintrag Exit
        private void OnExitRequested( object sender, MouseEventArgs e )
        {
            if ( e.Button != MouseButtons.Left )
            {
                return;
            }

            this.Close();
        }

        // Callback für einen Bookmark
        private void OnNavigateToBookmark( object sender, EventArgs e )
        {
            ToolStripButton button = sender as ToolStripButton;
            string title = button.Text;

            Bookmark bookmark = _bookmarks.Where( b => b.Title == title ).FirstOrDefault();
            if ( bookmark == null )
            {
                MessageBox.Show( "Error" );
                return;
            }

            webBrowser.Navigate( bookmark.URL );
        }

        #endregion
    }

    // Die Klasse Bookmarks, serialisierbar..
    [Serializable]
    [XmlRoot( "Bookmark" )]
    public class Bookmark
    {
        #region Public Properties

        [XmlElement( "Title" )]
        public string Title { get; set; }

        [XmlElement( "URL" )]
        public string URL { get; set; }

        #endregion
    }
}
 

Anhänge

Apllepie

Ensign
Dabei seit
Okt. 2007
Beiträge
153
nach einem neustart ist aber auch die array oder hashlist leer ;-)
ich verstehe gar nicht wozu man einen button braucht, der weitere buttons erstellt, normalerweise erstellt man doch bei jedem reload die gesamte seite neu, ich vermute mal, dass atreju nicht auch javascript implementieren will ^^

naja egal, ich würde wahrscheinlich einen browser auch eher in xna programmieren und die einzelnen steuerelemente zeichnen
 

character

Lt. Commander
Dabei seit
Juli 2008
Beiträge
1.615
Gruselig sind vor allem die Leerzeichen innerhalb von Klammern und die Zeilenumbrueche vor den geschweiften Klammern. Letzteres entspricht aber glaube ich sogar den Coding Conventions von MS. Kaum zu lesen sowas.
 

Apllepie

Ensign
Dabei seit
Okt. 2007
Beiträge
153
naja egal :-) ich hab das quasi als eigenes browserprojekt verstanden, für die navigationsleiste würde ich wohl auch auf eine windows forms bzw eher wpf anwendung zurück greifen, den webseiteninhalt dann aber mit xna darstellen, hier scheint das eher ein gerüst um eine art webview zu werden??

ich werde mich jetzt aber raus halten ^^ ;-)
 

Atreju93

Lieutenant
Ersteller dieses Themas
Dabei seit
Nov. 2010
Beiträge
586
Oha.. das Projekt von Holy ist meinem schon um welten überlegen..

Ich werde versuchen die Bookmarks mit der XML zu implementieren und zu verstehen.

Damit alle wissen an was dass ich eigentlich am arbeiten bin:

mein Projekt sieht bis jetzt so aus: Angehängt das Projekt.
 

Anhänge

Zuletzt bearbeitet:

captmcneil

Ensign
Dabei seit
Juni 2005
Beiträge
189
Gruselig sind vor allem die Leerzeichen innerhalb von Klammern und die Zeilenumbrueche vor den geschweiften Klammern. Letzteres entspricht aber glaube ich sogar den Coding Conventions von MS. Kaum zu lesen sowas.
Code-Conventions for the win! Ich bin da relativ eisern, und setze in Java meine öffnende Klammer in dieselbe Zeile, und bei C# in die neue - einfach weil's Konvention und Respekt gegenüber "native-Speakern" ist.

Trotzdem sollte man hier die schöne Lösung nicht schlechtreden, er hat sich Mühe gegeben, und ich denke, von dem Code kann der TE sicher einiges lernen.

Edit: Insbesondere gefällt mir, dass hier immer die { und } gesetzt werden, auch bei if-Einzeilern. Das sollten sich mal mehr schreibfaule Hacker anschauen :-)
 
Zuletzt bearbeitet:
Top