Laden...

Forenbeiträge von atmosfear Ingesamt 260 Beiträge

28.09.2016 - 15:21 Uhr

@Palladin007
Vielen Dank für deine weitere Antwort!

Langsam aber sicher und je mehr ich mich in das Thema einlese, geht mir ein Licht auf 😉
Ich baue jetzt ein paar Testszenarien um die Materie noch mehr zu vertiefen und dann denke ich, dass ich den (Groß)Teil verstanden habe...

Danke nochmal!
atmosfear

28.09.2016 - 14:44 Uhr

Hmmm, jetzt stehe ich irgendwie auf dem Schlauch...

Ich speichere ja Objekte vom Typ IOptionItem in meiner Liste, ja?
Wenn ich dann also eine typisierte Liste brauche (List<string>), dann muss ich Item x zuerst nach List<string> casten, ja?

Nutzt Du die generische Klasse, hast Du die typisierte Property

Wo genau meinst du?

Danke,
atmosfear

28.09.2016 - 11:41 Uhr

Also so


namespace Project.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            List<IOptionItem2> test1;

            List<string> sValues = new List<string>();
            sValues.Add("test1");
            sValues.Add("test2");

            test1 = new List<IOptionItem2>();
            test1.Add(new OptionItem2<string>(sValues));

            List<int> iValues = new List<int>();
            iValues.Add(1);
            iValues.Add(2);

            test1.Add(new OptionItem2<int>(iValues));

			IOptionItem2 oItem = test1[0];
			IList testValues = oItem.OptionValues;

			for (int i = 0; i < testValues.Count; i++)
				Console.WriteLine(testValues[i]);

			Pause();
		}

		public static void Pause()
		{
			Console.Write("Press any key to continue . . .");
			Console.ReadKey(true);
		}
	}
}

OptionItem dazu...


namespace Project.Test
{
    interface IOptionItem2
    {
		Type Type { get; }
		IList OptionValues { get; }
	}

    class OptionItem2<T> : IOptionItem2
    {
		private readonly List<T> _items;

		public OptionItem2(List<T> items_)
		{
			_items = items_;
		}

		public Type Type
		{
			get { return typeof(T); }
		}

		public IList OptionValues
		{
			get
			{
				return _items;
			}
		}
	}
}

Dann noch das dazu, dann muss ich auch den "Standard" string Typ nicht mehr angeben....


namespace Project.Test
{
    interface IOptionItem2
    {
		Type Type { get; }
		IList OptionValues { get; }
	}

    class OptionItem2<T> : IOptionItem2
    {
		private readonly List<T> _items;

		public OptionItem2(List<T> items_)
		{
			_items = items_;
		}

		public Type Type
		{
			get { return typeof(T); }
		}

		public IList OptionValues
		{
			get
			{
				return _items;
			}
		}
	}

	class OptionItem2 : OptionItem2<string>
	{
		public OptionItem2(List<string> items_) : base(items_) { }
	}
}

Wenn ich aber zum Weiterverarbeiten der Daten in einem Control, das wiederum eine Liste von strings verlangt, erneut typisierte Daten brauche, dann muss ich halt wieder von IList casten, oder?

Gruß,
atmosfear

28.09.2016 - 11:21 Uhr

@Palladin007

Also mein Code würde dann so aussehen:


            List<IOptionItem> test1;

            List<string> sValues = new List<string>();
            sValues.Add("test1");
            sValues.Add("test2");

            test1 = new List<IOptionItem>();
            test1.Add(new OptionItem2<string>(sValues));

            List<int> iValues = new List<int>();
            iValues.Add(1);
            iValues.Add(2);

            test1.Add(new OptionItem2<int>(iValues));

Und die veränderte OptionItem-Klasse dazu...


namespace Project.Test
{
    interface IOptionItem
    {
		Type Type { get; }
		IList OptionValues { get; }
	}

    class OptionItem2<T> : IOptionItem
    {
		private readonly List<T> _optionValues;

		public OptionItem2(IList items_)
		{
		}

		public Type Type
		{
			get { return typeof(T); }
		}

		public IList<T> OptionValues
		{
			get { return _optionValues; }
		}

		IList IOptionItem.OptionValues
		{
			get { return _optionValues; }
		}
	}
}

Wie komme ich aber dann trotzdem an meine Liste ran?


			IOptionItem oItem = test1[0];
			??? = oItem.OptionValues;

@Abt:

An diesen Ansatz dachte ich auch schon 😉
Habe aber eine Meeeeenge überladener Konstruktoren in den jeweiligen Klassen und da wollte ich mir die "Spezialinstanzen" sparen...

Danke!
atmosfear

28.09.2016 - 10:53 Uhr

Hallo und schönen Vormittag zusammen!

Um es kurz zu machen hier gleich mal ein Stückchen Code 😉


namespace Project.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            List<OptionItem> test1;

            List<string> sValues = new List<string>();
            sValues.Add("test1");
            sValues.Add("test2");

            test1 = new List<OptionItem>();
            test1.Add(new OptionItem<string>(sValues));

            List<int> iValues = new List<int>();
            iValues.Add(1);
            iValues.Add(2);

            test1.Add(new OptionItem<int>(iValues));

			OptionItem oItem = test1[0];
			if (oItem.Type == typeof(string))
			{
				OptionItem<string> testCast = oItem as OptionItem<string>;
				List<string> testValues = testCast.OptionValues;
			}
        }
    }
}

Und hier noch die dazugehörige "Datenklasse":


namespace Project.Test
{
    abstract class OptionItem
    {
        public OptionItem(Type type_)
        {
            Type = type_;
        }

        public Type Type { get; private set; }
    }

    class OptionItem<T> : OptionItem
    {
        private List<T> _items;

        public OptionItem(List<T> items_) : base(typeof(T))
        {
            _items = items_;
        }

        public List<T> OptionValues
        {
            get
            {
                return _items;
            }
        }
    }
}

Meine eigentliche Frage ist nun, wie ich auf die interne Liste des OptionItem-Objekts zugreifen kann, ohne einen Cast zu brauchen?! Geht das überhaupt bzw. welche Design-Patterns würden sich hierfür anbieten?

Die Anforderung ist eine Liste von Optionen zu erstellen, die wiederum eine Liste von Werten beinhalten können. Diese Werte können nun natürlich von unterschiedlichen Typen sein (string, int, byte ...).
Die Werte werden dann im Anschluss mit verschiedenen Custom-Controls visualisiert.

Ich habe auch bereits überlegt einfach eine Object-List zu verwenden - dies möchte ich jedoch so gut es geht vermeiden....

Vielen Dank für eure Ratschläge und Hilfe!
Ich hoffe ich habe mich klar genug ausgedrückt 😉
Wenn man schon tief in einem Thema festgefahren ist vergisst man manchmal Details zu erklären - also bitte, wenn etwas an meiner Fragestellung unklar ist - bitte fragen... 😉

atmosfear

16.10.2015 - 11:53 Uhr

Probiert - nutzt leider nichts...

atmosfear

16.10.2015 - 11:24 Uhr

Werte C# Gemeinde,

ich möchte eine Custom ListBox erstellen und habe ein Problem mit der OnDrawItem-Methode der Komponente.
Bevor ich das Problem näher beschreibe hier der Code:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ColorTools
{
    class CListBox : ListBox
    {
        private ushort _padding;

        public CListBox()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
            //this.DrawItem += CListBoxDrawItem;
            this.ItemHeight = 48;
            //this.DoubleBuffered = true;
        }

        public ushort CListBoxPadding
        {
            set { _padding = value;  }
            get { return _padding; }
        }

        //private void CListBoxDrawItem(object sender, DrawItemEventArgs e)
        //{
        //    const TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;

        //    string itemText;

        //    int imageWidth;
        //    int imageHeight;

        //    e.DrawBackground();
        //    Graphics g = e.Graphics;
        //    Rectangle bound = e.Bounds;

        //    if (DesignMode)
        //    {
        //        imageWidth = 10;
        //        imageHeight = 10;
        //        itemText = "ColorListBox";
        //    }
        //    else
        //    {
        //        CColor item = (CColor)Items[e.Index];
        //        imageWidth = item.ColorIcon.Width;
        //        imageHeight = item.ColorIcon.Height;
        //        itemText = item.ColorName;

        //        Brush backBrush = new SolidBrush(Color.FromArgb(255, 236, 239, 241));
        //        g.FillRectangle(backBrush, new Rectangle(bound.Left, bound.Top + _padding, bound.Left + imageWidth + (2 * _padding), bound.Bottom - (2 * _padding)));
        //        g.DrawImage(item.ColorIcon, bound.Left + _padding, bound.Top + (bound.Height / 2) - (imageHeight / 2));
        //    }

        //    bound.X = bound.Left + imageWidth + (2 * _padding) + _padding;
        //    TextRenderer.DrawText(e.Graphics, itemText, e.Font, bound, e.ForeColor, flags);

        //    e.DrawFocusRectangle();
        //}

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            const TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;

            if (e.Index >= 0)
            {
                string itemText;
                int imageWidth;
                int imageHeight;

                e.DrawBackground();

                Rectangle bound = e.Bounds;

                if (DesignMode)
                {
                    imageWidth = 10;
                    imageHeight = 10;
                    itemText = "ColorListBox";
                }
                else
                {
                    // CColor item = (CColor)Items[e.Index];
                    imageWidth = 64; //item.ColorIcon.Width;
                    imageHeight = 32; //item.ColorIcon.Height;
                    itemText = "Test"; //item.ColorName;

                    Brush backBrush = new SolidBrush(Color.FromArgb(255, 236, 239, 241));
                    e.Graphics.FillRectangle(backBrush, new Rectangle(bound.Left, bound.Top + _padding, bound.Left + imageWidth + (2 * _padding), bound.Bottom - (2 * _padding)));

                    Brush brush = new SolidBrush(Color.FromArgb(255, 255, 0, 0));
                    Bitmap bmp = new Bitmap(64, 32);
                    using (Graphics graph = Graphics.FromImage(bmp))
                    {
                        Rectangle ImageSize = new Rectangle(0, 0, 64, 32);
                        graph.FillRectangle(brush, ImageSize);
                    }
                    e.Graphics.DrawImage(bmp, bound.Left + _padding, bound.Top + (bound.Height / 2) - (imageHeight / 2));

                    //backBrush = new SolidBrush(Color.FromArgb(255, 0, 239, 241));
                    //e.Graphics.FillRectangle(backBrush, new Rectangle(bound.Left, bound.Top + _padding, bound.Left + imageWidth + (2 * _padding), bound.Bottom - (2 * _padding) - 30));
                }

                bound.X = bound.Left + imageWidth + (2 * _padding) + _padding;
                TextRenderer.DrawText(e.Graphics, itemText, e.Font, bound, e.ForeColor, flags);

                e.DrawFocusRectangle();
                base.OnDrawItem(e);
            }
        }
    }
}

Problem ist, dass das darunterliegende Rect (ich möchte so eine Art Google-like-Panel) machen und das zugehörige Bild nicht immer sauber
dargestellt werden. Wenn ich in der Liste auf verschiede Items klicke oder die Liste einfach nur durchscrolle,
verschwindet das Image teilweise wieder und wird nicht neu gezeichnet.

Aus diesem Grund habe ich auch bereits das DoubleBuffering getestet - leider ohne Erfolg...
Auch das "Verschieben" der e.DrawBackGround oder der e.DrawFocusRectangle Methode brachte nicht das gewünschte Ergebnis...
Die Abhandlung in einer eigenen Methode (siehe CListBoxDrawItem) brachte auch nichts ein...

Irgendwelche Ideen eurerseits?
Vielen Dank für eure Hilfe,
atmosfear

15.10.2015 - 08:05 Uhr

Morgen,

habe mein Problem jetzt folgendermaßen mit einer Property gelöst...

		public Bitmap ColorIcon
		{
			get
			{
				Brush brush = new SolidBrush(_color);
				Bitmap bmp = new Bitmap(32, 32);
				using (Graphics graph = Graphics.FromImage(bmp))
				{
					Rectangle ImageSize = new Rectangle(0, 0, 32, 32);
					graph.FillRectangle(brush, ImageSize);
				}
				return bmp;
			}
		}

Und die zugehörige Column im Grid...

			DataGridViewImageColumn column4 = new DataGridViewImageColumn();
			column4.DataPropertyName = "ColorIcon";
			dataGridView1.Columns.Add(column4);

Gruß und danke,
atmosfear

14.10.2015 - 15:16 Uhr

@Cat,

vielen Dank, das hat funktioniert!
Jetzt frage ich mich nur noch, wie ich die Property ColorValue (gibt eine Color zurück) an ein
DataGridViewImageCell-Control binden kann?!

Edit: Ich möchte also ein farbiges Rect innerhalb der Colum anzeigen, das die Farbe repräsentiert...

Vielen Dank,
atmosfear

14.10.2015 - 09:08 Uhr

Hallo zusammen,

ich versuche folgendes Problem umzusetzen:

Ich habe eine Basisklasse CColor, die die grundlegenden Eigenschaften einer Farbe beschreibt:

	class CColor
	{
		#region Private Variables

		private string _name;
		private Color _color;

		#endregion

		#region Constructor
		public CColor()
		{
			_name = "";
			_color = Color.FromArgb(0, 0, 0, 0);
		}

		public CColor(string name_, Color color_)
		{
			_name = name_;
			_color = color_;
		}
		
		#endregion

		#region Public Properties

		public string ColorName
		{
			get { return _name; }
			set { _name = value; }
		}

		public string ColorVal
		{
			get { return _color.ToString(); }
		}

		public Color ColorValue
		{
			get	{ return _color; }
			set	{ _color = value; }
		}

		public virtual string ColorRange
		{
			get { return ""; }
		}

		#endregion
	}

Davon leite ich mehrere Farbentypen ab (also Hersteller), die wiederum eigene Eigenschaften haben können:

	class CCitadel : CColor
	{
		#region Private Variables

		private EColorType _colorType;
		
		#endregion

		#region Constructor

		public CCitadel()
		{
			_colorType = EColorType.Base;
		}

		public CCitadel(string name_, Color color_)
			: base(name_ , color_)
		{

		}

		public CCitadel(string name_, Color color_, EColorType colorType_)
			: base(name_, color_)
		{
			_colorType = colorType_;
		}

		#endregion

		#region Public Properties

		public EColorType ColorType
		{
			get { return _colorType; }
			set	{ _colorType = value; }
		}

		public override string ColorRange
		{
			get { return _colorType.ToString(); }
		}

		#endregion
	}

Dann legen ich die einzelnen Farben folgendermaßen in einem Dictionary an:
Das Dictionary verwende ich erstens zu Übungszwecken und zweitens über den Index schnell alle Farben einer bestimmen Marke abgreifen zu können (Filter, verschiedene Ansichten, usw...)

			Dictionary<EColorMake, List<CColor>> colors = new Dictionary<EColorMake, List<CColor>>();

			List<CColor> vallejo_colors = new List<CColor>();
			vallejo_colors.Add(new CVallejo("color1", Color.FromArgb(255, 255, 255, 255), EColorBrand.ModelColor));
			vallejo_colors.Add(new CVallejo("color2", Color.FromArgb(255, 255, 0, 0), EColorBrand.ModelAir));
			vallejo_colors.Add(new CVallejo("color3", Color.FromArgb(255, 0, 255, 0), EColorBrand.GameColor));

			List<CColor> citadel_colors = new List<CColor>();
			citadel_colors.Add(new CCitadel("color4", Color.FromArgb(255, 0, 0, 255), EColorType.Base));
			citadel_colors.Add(new CCitadel("color5", Color.FromArgb(255, 0, 0, 0), EColorType.Drybrush));

			colors.Add(EColorMake.Vallejo, vallejo_colors);
			colors.Add(EColorMake.Citadel, citadel_colors);
			

Dem ganzen übergeordnet sind natürlich die Enumerations definiert:

	public enum EColorMake : byte
	{
		Common,
		Vallejo,
		Citadel
	}

	public enum EColorType : byte
	{
		Base,
		Layer,
		Wash,
		Drybrush,
		Glaze
	}

	public enum EColorBrand: byte
	{
		ModelColor,
		ModelAir,
		GameColor
	}

Jetzt versuche ich alle Farben in einem DatagridView anzuzeigen, wobei die Property "ColorRange" der einzelnen Objekte verschiedenen Inhalt (.ToString()) anzeigen kann.

			List<CColor> flatList = colors.Values		// to get just the List<CColor>s
								.SelectMany(x => x)		// flatten
								.ToList();              // listify

			foreach (CColor color in flatList)
				bindingSource1.Add(color);

			dataGridView1.AutoGenerateColumns = false;
			dataGridView1.AutoSize = true;
			dataGridView1.DataSource = bindingSource1;

			// initialize and add a text box column.
			DataGridViewColumn column1 = new DataGridViewTextBoxColumn();
			column1.DataPropertyName = "ColorName";
			column1.Name = "Color";
			dataGridView1.Columns.Add(column1);

			DataGridViewColumn column2 = new DataGridViewTextBoxColumn();
			column2.DataPropertyName = "ColorVal";
			column2.Name = "ColorVal";
			dataGridView1.Columns.Add(column2);

			DataGridViewColumn column3 = new DataGridViewTextBoxColumn();
			column3.DataPropertyName = "ColorRange";
			column3.Name = "ColorRange";
			dataGridView1.Columns.Add(column3);

Leider kann ich die flatList nicht an das Grid binden, da sich unterschiedliche Typen in der Liste befinden.
Ich dachte, dass dies durch den Polymorphismus (alles kommt von einer Basisklasse) möglich wäre....

Hhhhmmm, irgendwo happerts da bei mir bei den Grundlagen denke ich, denn die Property ColorRange hätte ich ja eigentlich in allen Klassen definiert (als override der Basisklasse)....

Gibt es (vielleicht) bessere Ansätze für meine gewünschten Datenstruktur?

Vielen Dank für eure Hilfe!
atmosfear

27.05.2012 - 20:02 Uhr

Ja, sorry, hab das nicht auf Anhieb gesehen!
Habe jetzt einfach die BinaryCopyEventArgs Klasse um eine Property erweitert - und das war's.
Frage mich nur immer wofür man dann die FileListCopyEventArgs braucht - das habe ich noch nicht ganz verstanden...

Gruß
atmosfear

27.05.2012 - 17:53 Uhr

Ok gut, jetzt muss ich nur noch auf den aktuellen Filenamen zugreifen können?
Wie kann ich die FileListCopyEventArgs.cs implementieren?

So sieht's bis dato aus:

        private void btnNext_Click(object sender, EventArgs e)
        {
            backgroundWorker.RunWorkerAsync();
        }

        void bCopy_BinaryCopyEvent(object sender, BinaryCopyEventArgs e)
        {
            // Auf das BinaryCopy Event reagieren und beim BGW das ProgressChanged Event auslösen und die BinaryCopyEventArgs übergeben
            backgroundWorker.ReportProgress(Convert.ToInt32(e.Percent), (object)e);
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Event des BinaryCopiers registrieren
            this.bCopy_.BinaryCopyEvent += new BinaryCopyEventHandler(bCopy_BinaryCopyEvent);

            // Kopie der Datei starten
            foreach (DataRow dr in this.dataTable_.Rows)
            {
                this.bCopy_.CopyFolder(dr["m_settled_source"].ToString(), dr["m_target"].ToString(), true);
            }
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // EventArgs abfragen
            BinaryCopyEventArgs binaryArgs = (e.UserState as BinaryCopyEventArgs);

            // Prozessbar aktualisieren
            tsProgressBar.Value = e.ProgressPercentage;
            // Datendurchsatz in einem Label anzeigen
            tsslAction.Text = binaryArgs.KbPSec.ToString("N").Substring(0, binaryArgs.KbPSec.ToString("N").Length - 3) + " Kb/sec";
            // Restzeit in einem Label anzeigen
            //tsslRemaning.Text = binaryArgs.Remaning.ToString();
        }

Im Progressbar hätte ich gerne das aktuelle File angezeigt...

Danke!
atmosfear

27.05.2012 - 16:49 Uhr

Hallo und schönen Abend zusammen!

Ich versuche die von t2t entwickelte Komponente einzusetzen.
Meine Frage nun:
Was mache ich, wenn ich mehrere Ordner an ein bestimmtes Ziel kopieren möchte?
Es gibt zwar eine Methode für das Kopieren von Ordnern - leider kann ich aber keine Liste von Ordnern übergeben, oder habe ich etwas übersehen?

Ich weiss nicht, wie ich in einer Schleife mehrere Ordner kopieren und dann auch nocht
das Threading beibehalten kann?!

Danke!
atmosfear

21.05.2012 - 21:06 Uhr

Hallo nochmal,

ich habe das jetzt folgendermassen gelöst:

            Properties.Settings appSettings = new Properties.Settings();
            if (appSettings.UpdateRequired)
            {
                appSettings.Upgrade();
                appSettings.UpdateRequired = false;
                appSettings.Save();
            }

Einfach in der IDE eine neue Einstellungen mit UpdateRequired mit dem Default-Wert True angelegt.
Wenn ich die Versionsnummer nun raufdrehe dann werden die alten Settings übernommen.
Im Anschluss daran wird das Flag in der user.config auf False gesetzt - somit werden die Settings nicht jedesmal aktualisiert.

Sollte so funktionieren denke ich...

Gruß
atmosfear

21.05.2012 - 20:20 Uhr

Hallo und schönen Abend!

Zuerst einmal DANKE an allle Beteiligten für eure Antworten!

Ich habe es jetzt so gemacht, dass ich in den Properties/Settings.settings 3 Werte definiert,
die als default den wert "undefined" haben.
Dann habe ich ganz normal abgefragt ob dort etwas anderes steht, also

    static class Program
    {
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            
            string temp = Properties.Settings.Default.DatabasePath;
            if (String.IsNullOrEmpty(temp) || temp == "undefined")
            {
                dlgConfigWizard wizard = new dlgConfigWizard();
                wizard.ShowDialog();
                Application.Run();
            }
            else
                Application.Run(new frmMain());
        }
    }

Funktioniert so gut, muss auch nicht extra auf das Vorhandensein der user.config abfragen.
Was ich allerdings noch nicht ganz verstehe ist die Geschichte von FZelle, also das mit den
beiden Flags die auf einen Umzug checken?! Kann mir da noch einmal jemand auf die Sprünge helfen?

Da ich gerade das Codeschnippsel oben gepostet habe, auch noch eine Frage zu den Application.Run Methoden.
Passt das so, oder bekomme ich da in irgendeiner Form Probleme mit dem Hauptthread?

Ich fahre folgendermassen fort (in einem vorgeschalteten Dialog):

        private void btnNext_Click(object sender, EventArgs e)
        {
            this.appSettings_.DatabasePath = txtDbDir.Text.ToString();
            this.appSettings_.Save();

            this.Close();
            this.proceed_ = true;
            
            frmMain frmMain = new frmMain();
            frmMain.Show();
        }

        private void dlgConfigWizard_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (!this.proceed_)
                Application.Exit();
        }

und dann im mainForm:

        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

Danke!
atmosfear

21.05.2012 - 12:44 Uhr

Hallo und Mahlzeit zusammen!

Ich möchte gerne mehrere Usersettings speichern und weiss, dass diese in der user.config im jeweiligen Benutzerordner gespeichert werden.
Jetzt möchte ich gernen beim Start meiner Applikation (falls noch keine Settings vorhanden sind) einen Configuration Wizard starten, der die Startbedingungen festlegt.
In Visual Studio habe ich 3 Variablen unter den Einstellungen vom Typ Benutzer angelegt.

Meine Fragen sind nun:

(1) Ich weiss, dass das user.config File erst beim Speichern abgelegt wird. Wo stehen die Werte aber anfangs? In dem appname.exe.config File?
Ich dachte, dass dort nur die Anwendungseinstellungen abgelegt werden?

(2) Kann ich mir das Anlegen der Variablen in der Entwicklungsumgebung sparen?

(3) Wie kann ich dann abfragen ob bereits Einstellungen vorhanden sind? Muss ich hier auf das Vorhandensein einer user.config Datei prüfen?
Oder kann ich ganz normal über Properties.Settings.Default.XXX abfragen?
Denn wenn ja, woher nimmt die Applikation dann die Einstellungen her?

Vielen Dank!
atmosfear

25.03.2009 - 15:52 Uhr

Hallo nochmal!

@LaTino
Erstmal DANKE für deine Tipps! Der Link zu den Sachen XPath hat mir sehr weitergeholfen!

Ich habe nun folgende Lösung gefunden. Ist zwar vielleicht nicht die eleganteste, aber funktioniert:

            string xmlFile1 = @"M:\01 Hard & Heavy Mac.xml";
            string xmlFile2 = @"M:\02 Hard & Heavy Pc.xml";
            string actArtist;
            string actAlbum;
            string actTrack;

            XmlDocument xmlDoc = new XmlDocument();
            XmlElement root;
            XmlNodeList xmlDictNodeList;
            TextWriter tw;

            // parse mac xml output and fill dataset
            xmlDoc.Load(xmlFile1);
            root = xmlDoc.DocumentElement;
            xmlDictNodeList = root.SelectNodes("dict/dict/dict");
            tw = new StreamWriter(@"M:\iTunesExportMac.txt", false);

            foreach (XmlNode xmlDictNode in xmlDictNodeList)
            {
                actArtist = String.Empty;
                actAlbum = String.Empty;
                actTrack = String.Empty;

                XmlNodeList xmlKeyNodeList = xmlDictNode.SelectNodes("key");
                foreach (XmlNode xmlKeyNode in xmlKeyNodeList)
                {
                    if (xmlKeyNode.NodeType == XmlNodeType.Element)
                    {
                        if (xmlKeyNode.InnerText == "Name" || xmlKeyNode.InnerText == "Artist" || xmlKeyNode.InnerText == "Album")
                        {
                            XmlNode xmlValue = xmlKeyNode.NextSibling;
                            if (xmlValue != null)
                            {
                                switch (xmlKeyNode.InnerText)
                                {
                                    case "Name":
                                        actTrack = xmlValue.InnerText;
                                        break;
                                    case "Artist":
                                        actArtist = xmlValue.InnerText;
                                        break;
                                    case "Album":
                                        actAlbum = xmlValue.InnerText;
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                    }
                }
                DataRow newRow = dsMac.Tables["track"].NewRow();
                newRow["artist"] = actArtist;
                newRow["album"] = actAlbum;
                newRow["track"] = actTrack;
                dsMac.Tables["track"].Rows.Add(newRow);
                tw.WriteLine(actArtist + " - " + actAlbum + @"\" + actTrack);
            }

            tw.Close();

Nun habe ich 2 Exportfiles (die Logik oben wird 2 mal durchlaufen), die folgendermassen aussehen:

0 Zimmershole - Legion Of Flames\The Hole Is The Law
1 Zimmershole - Legion Of Flames\Death To The Dodgers Of Soap
2 Zimmershole - Legion Of Flames\Re-Anaconda
3 Zimmershole - Legion Of Flames\Legion Of Flames
4 Zimmershole - Legion Of Flames\Well Of Misfortune
5 Zimmershole - Legion Of Flames\Aerometh
6 Zimmershole - Legion Of Flames\Evil Robots
7 Zimmershole - Legion Of Flames\Gender Of The Beast
8 Zimmershole - Legion Of Flames\Rock Move 47
9 Zimmershole - Legion Of Flames\1000 Miles Of Cock
10 Zimmershole - Legion Of Flames\Sodomanaz
11 Zimmershole - Legion Of Flames\That's How Drunks Drink
12 Zimmershole - Legion Of Flames\Doggy Style
13 Zimmershole - Legion Of Flames\This Flight Tonight
14 Zimmershole - Legion Of Flames\White Trash Momma
15 Zimmershole - Legion Of Flames\Gaysong
16 Zimmershole - Legion Of Flames\Mushroom Mattress

Und Datei 2:

0 Rammstein - Totes Fleisch\Outro
1 Rammstein - Totes Fleisch\Du Riechst So Gut (3) - Migräne Rmx
2 Rammstein - Totes Fleisch\Rammstein (2) - Eskimos & Egypt Rmx
3 Rammstein - Totes Fleisch\Asche Zu Asche
4 Rammstein - Totes Fleisch\Bück Dich
5 Rammstein - Totes Fleisch\Sehnsucht
6 Rammstein - Totes Fleisch\Feuerräder
7 Rammstein - Totes Fleisch\Herzeleid (2)
8 Rammstein - Totes Fleisch\Du Riechst So Gut (2) - Migräne Rmx
9 Rammstein - Totes Fleisch\Angel - English version
10 Rammstein - Totes Fleisch\Wilder Wein
11 Rammstein - Totes Fleisch\Heirate Mich
12 Rammstein - Totes Fleisch\Tier
13 Rammstein - Totes Fleisch\Alter Mann
14 Rammstein - Totes Fleisch\Spiel Mit Mir
15 Rammstein - Totes Fleisch\Seemann
16 Carcass - Reek Of Putrefaction\Malignant Defecation

Ich möchte diese beiden Outputs, also eigentlich Datatables miteinander vergleichen.
Habe es schon mit Merge usw. versucht, komme aber nicht zum Ergebnis?!

            // compare the 2 datasets
            DataTable tableMac = dsMac.Tables["track"];
            DataTable tablePc = dsPc.Tables["track"];

            if (tableMac.Rows.Count != tablePc.Rows.Count)
            {
                DataRow[] drMacSorted = dsMac.Tables["track"].Select("", "artist desc");
                DataRow[] drPcSorted = dsPc.Tables["track"].Select("", "artist desc");
            }
            ...
            ...


Ich muss irgendwie heraussfinden wo die Unterschiede zwischen den beiden Files liegen....

Danke für Eure Hilfe!
atmosfear

24.03.2009 - 12:57 Uhr

Hallo nochmal!

Ich hab's jetzt mal so versucht:

            string xmlFile1 = @"M:\01 Hard & Heavy.xml";
            string xmlFile2 = @"M:\02 Hard & Heavy.xml";

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlFile1);

            XmlElement root = xmlDoc.DocumentElement;
            XmlNodeList xmlNodeList = root.SelectNodes("/dict/key");

Leider ist die XmlNodeCollection leer?!
Habe auch schon "dict/dict/key" versucht, auch ohne Erfolg!
Ich gebe euch ein wenig mehr von dem XML Element, damit ihr die Struktur besser beurteilen könnt.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Major Version</key><integer>1</integer>
	<key>Minor Version</key><integer>1</integer>
	<key>Application Version</key><string>8.1</string>
	<key>Features</key><integer>5</integer>
	<key>Show Content Ratings</key><true/>
	<key>Music Folder</key><string>file://localhost/XXX/</string>
	<key>Library Persistent ID</key><string>201FA6E10693078D</string>
	<key>Tracks</key>
	<dict>
		<key>93866</key>
		<dict>
			<key>Track ID</key><integer>93866</integer>
			<key>Name</key><string>Outro</string>
			<key>Artist</key><string>Rammstein</string>
			<key>Album Artist</key><string>Rammstein</string>

DANKE
atmosfear

24.03.2009 - 12:40 Uhr

@Abt
Danke für den Tipp! Na ja, wie ein konformes XML Dokument auszusehen hat wäre mir durchaus bewusst, aber der Output kommt eben direkt aus iTunes und lässt sich, wie ja LaTine auch schon bemerkt hat, nicht verändern!

@LaTino
Danke - das ist doch mal ein Ansatz mit dem ich weiterkommen sollte?!
Ja, das XML ist wirklich geil! Da schiesst Apple wieder mal den Vogel ab in punkto Normen und Standards 😃

Ich versuche nun mit den von euch genannten Tipps weiter zu kommen und melde mich später wieder...

DANKE
atmosfear

24.03.2009 - 09:33 Uhr

Hallo und schönen Vormittag zusammen!

Ich versuche ein XML File zu parsen und die Ergebnisse in ein Dataaset einzulesen.
Mit der direkten "ReadXML" Methode hatte ich leider keinen Erfolg, da passt wohl das Quellformat nicht und ich bekomme zu viele Errors.

Nun möchte ich mittels eines XmlTextReaders das File lesen und nachträglich in ein Dataset einlesen.
Aber wie kann ich das folgende Format parsen?
Bei dem folgenden Ausschnitt handelt es sich um ein Exportfile von iTunes.
Dort wurde einfach eine Wiedergabeliste als XML exportiert...

<dict>
			<key>Track ID</key><integer>93866</integer>
			<key>Name</key><string>Outro</string>
			<key>Artist</key><string>Rammstein</string>
			<key>Album Artist</key><string>Rammstein</string>

Ich müsste also vorher auch den Namen schauen, also z.B.: TrackID und dann noch den Wert des "darunterliegenden" Elements also den <integer> auslesen.
Wie komme ich aber vom aktuellen Element auf das nächste - und wie kann ich prüfen ob es überhaupt ein nächstes gibt?

Hier mein Code bisher (nur ein Test - ergibt also noch keinen wirklichen Sinn!):

            string xmlFile1 = @"M:\Test1.xml";
            string xmlFile2 = @"M:\Test2.xml";

            XmlTextReader xmlReader1 = new XmlTextReader(xmlFile1);
            
            DataSet dsFile1 = new DataSet("xmlFile1");
            dsFile1.Tables.Add(new DataTable("tracks"));
            DataColumn dcTrackName = new DataColumn("trackname", System.Type.GetType("System.String")); 
            dsFile1.Tables["tracks"].Columns.Add(dcTrackName);

            while (xmlReader1.Read())
            {
                if (xmlReader1.NodeType == XmlNodeType.Element)
                {
                     DataRow newRow = dsFile1.Tables["tracks"].NewRow();
                     newRow["trackname"] = xmlReader1.Name;
                    dsFile1.Tables["tracks"].Rows.Add(newRow);
                    }
                }
            }

DANKE
atmosfear

13.02.2009 - 11:38 Uhr

Hallo und Mahlzeit zusammen,

ich versuche in einem DataGridView Rows zu suchen, die einem bestimmten Kriterium entsprechen.
Dies geht ja grundsätzlich mit der "BindingSource.Find" Methode.

Ok, bei mir muss man sich das Ganze aber so vorstellen:

Liste von Alben
---- KLASSE ALBUM
-------- Liste von Duplikaten, die dem Albumnamen entsprechen

Wenn ein Album also einen "Namensvetter" hat (oder auch mehrere), dann wird innerhalb des aktuellen Albumobjekts eine Liste angelegt, die eben diese Alben enthält.

Im "RowPrePaint" Event des DatagridViews versuche ich nun diese Alben im Grid zu finden und farblich zu hinterlegen.

Also:

if (album.AlbumNameEquates.Count > 0)
{
   foreach (Album albumEquate in album.AlbumNameEquates)
   // HIER MUSS ICH DEN ROWINDEX DES ALBUMS FINDEN??
}

Nun habe ich es schon mit der BindingSource probiert - geht aber leider nicht, da die BindingSource eine Property haben möchte, nach der sie vergleich.
Ich möchte aber das "Objekt" albumEquate mit der zugrundeliegenden DataSource vergleichen und den RowIndex herausfinden!

Hat jemand eine Ideen und/oder einen Tipp für mich?

DANKE
atmosfear

10.02.2009 - 19:09 Uhr

@herbivore

Danke abermals für deine Antwort!

zu 1. Was ist daran unklar? So ziemlich alles 😃

Bit dato habe ich folgenden Code:

                                    TagLib.ByteVector byteVector = cover.Data;
                                    MemoryStream mStream = new MemoryStream(byteVector.Data);
                                    Image coverImage = Image.FromStream(mStream, false, true);
                                    Bitmap coverBitmap = new Bitmap(coverImage);

                                    Rectangle rect = new Rectangle(0, 0, coverBitmap.Width, coverBitmap.Height);
                                    BitmapData bmpData = coverBitmap.LockBits(rect, ImageLockMode.ReadOnly,
                                        coverBitmap.PixelFormat);

                                    IntPtr ptr = bmpData.Scan0;
                                    int bytes = bmpData.Stride * coverBitmap.Height;
                                    byte[] rgbValues = new byte[bytes];

                                    Marshal.Copy(ptr, rgbValues, 0, bytes);
                                    coverBitmap.UnlockBits(bmpData);

Ich weiss nun nur nicht von was ich genau die MD5 berechnen soll?
Von allen RGB Werten, oder wie?

Der Ansatz denke ich stimmt doch schon mal, zumindest laut MSDN 😃
Wie du siehst ich bemüh' mich ja, aber irgendwie weiss ich noch nicht, auf was du hinaus willst 😦

DANKE
atmosfear

10.02.2009 - 17:13 Uhr

Hallo!

@herbivore
Danke für deine Idee. Allerdings kann ich damit nicht sehr viel anfangen.
Habe auch soeben gesehen, dass du schon einmal einem User hier im Forum den gleichen Tipp gegeben hast,
aber auch hier stehe ich irgendwie auf der Leitung?!

  1. Was meinst du genau mit "Bitmap ins Format 32bpp normalisieren"
  2. Aus den Infos eine MD5 Summe berechnen?
... MD5.Create().ComputeHash(mStream); ...

Aus dem Stream, oder wie?

Kannst du mir da etwa ein wenig unter die Arme greifen?
Hab mit MD5 Sachen und dergleichen noch nie etwas zu tun gehabt...

DANKE
atmosfear

@pdelvo
Auch ein herbi macht mal einen Fehler 😃

09.02.2009 - 19:03 Uhr

@herbivore

Danke herbivore, hast mir sehr weiter geholfen!
Jetzt habe ich "nur" mehr ein riiiiesen Speicherproblem,
aber sehe selbst meinen Beitrag im anderen Forum.

Speicherprobleme

DANKE
atmosfear

09.02.2009 - 19:02 Uhr

Hallo und einen schönen guten Abend zusammen!

Ich lese mittels der tagLib# Library Header von Mp3 Dateien aus und möchte mir für
jeden Track ein Cover in einem Track-Objekt hinterlegen.
Leider bekomme ich hier ein massives Speicherproblem!
Sagen wir mal ich habe 10.000 Mp3 Dateien und speichere für jeden Tracks ein Album-Bitmap mit ab.
Das macht dann ca. 150k Bild pro Datei, also 1500000, umgerechnet also ca. 1,5 GB Speicher (RAM)
Nun möchte ich vorher vergleichen ob nicht das Cover jedes Tracks des entsprechenden Albums gleich ist und irgendwie
eine Refernz auf nur 1 Bitmap anlegen!?
Klar, soweit?

Hier mein Code:

                            // get all covers from each tag
                            if (file.Tag.Pictures.Length > 0)
                            {
                                tagCovers = new List<Bitmap>();
                                foreach (TagLib.IPicture cover in file.Tag.Pictures)
                                {
                                    TagLib.ByteVector byteVector = cover.Data;
                                    MemoryStream mStream = new MemoryStream(byteVector.Data);
                                    Image coverImage = Image.FromStream(mStream, false, true);
                                    Bitmap coverBitmap = new Bitmap(coverImage);
                                    tagCovers.Add(coverBitmap);
                                    mStream.Dispose();
                                    coverImage.Dispose();

                                }
                            }

Wie kann ich nun, erstens abfragen ob das Cover gleich ist und zweitens nur eine Objektreferenz in meine Liste legen und nicht jedesmal ein neues Bitmap Objekt?
Fragt ruhig, wenn euch an meiner Vorgehensweise irgend etwas unklar ist!

DANKE für eure Hilfe und Tipps!
atmosfear

07.02.2009 - 13:14 Uhr

Hallo und schönen Nachmittag zusammen!

Ja ja, kauf habe ich das eine Problem gelöst, komme ich auch schon mit dem nächsten 😃

Ich möchte eine Databinding für eine Picturebox verwenden, und vorher das anzuzeigende Bild entsprechend verkleinern und einpassen.
Wenn gar kein Bild vorhanden ist, gibt diese Funktion "null" zurück. Mit diesem Wert
kann die Picturebox allerdings nichts anfangen und schmeisst eine Exception.

Hier der Code dazu:
Im Main:

                pBoxTagCover.DataBindings.Add(new Binding("Image", this.trackBinder_, "TagCover"));

Und in der Klasse:

        public BitmapTagCover
        {
            get { return ResizeTagCover(); }
        }
        
        private BitmapResizeTagCover()
        {
            Bitmap imgOrig = null;
            Bitmap imgShown = null;

            if (this.tagCovers_.Count > 0)
            {
                double divideBy, divideByW, divideByH;
                Graphics g;

                imgOrig = this.tagCovers_[0];
                divideByW = ((double)imgOrig.Width / 100);
                divideByH = ((double)imgOrig.Height / 100);

                if (divideByW > 1 || divideByH > 1)
                {
                    if (divideByW > divideByH)
                        divideBy = divideByW;
                    else divideBy = divideByH;

                    imgShown = new Bitmap((int)((double)imgOrig.Width / divideBy), (int)((double)imgOrig.Height / divideBy));
                    imgShown.SetResolution(imgOrig.HorizontalResolution, imgOrig.VerticalResolution);
                    g = Graphics.FromImage(imgShown);
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.DrawImage(imgOrig, new Rectangle(0, 0, (int)((double)imgOrig.Width / divideBy), (int)((double)imgOrig.Height / divideBy)), 0, 0, imgOrig.Width, imgOrig.Height, GraphicsUnit.Pixel);
                    g.Dispose();
                }
                else
                {
                    imgShown = new Bitmap(imgOrig.Width, imgOrig.Height);
                    imgShown.SetResolution(imgOrig.HorizontalResolution, imgOrig.VerticalResolution);
                    g = Graphics.FromImage(imgShown);
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.DrawImage(imgOrig, new Rectangle(0, 0, imgOrig.Width, imgOrig.Height), 0, 0, imgOrig.Width, imgOrig.Height, GraphicsUnit.Pixel);
                    g.Dispose();
                }
                imgOrig.Dispose();
            }
                      
            return imgShown;
        }

Erstens bekomme ich von meiner Funktion den Typ Bitmap zurück und die Picturebox braucht einen Wert vom Typ Image, oder?
Und zweitens kann eben die Picturebox, falls kein Coverbild vorhanden, nichts mit dem Wert null anfangen!?

Hat jemand von euch eine Idee und/oder Tipp für mich?

DANKE
atmosfear

07.02.2009 - 13:06 Uhr

Hallo und schönen Nachmittag zusammen!

Habe das Problem nun lösen können und will euch die Lösung natürlich nicht vorenthalten.

Zum Synchronisiern müssen alle Controls an der selben BindingSource hängen, da ansonsten verschiedene CurrencyManager verwendet werden und sich die Controls dann nicht mehr synchronisieren lassen (habe ich gelesen)

Egal, der fertige Code sieht so aus:

                this.albumBinder_ = new BindingSource();
                this.albumBinder_.DataSource = this.albums_;
                dgridAlbum.DataSource = this.albumBinder_;
                
                this.trackBinder_ = new BindingSource();
                this.trackBinder_.DataSource = this.albumBinder_;
                this.trackBinder_.DataMember = "Tracks";
                dgridTrack.DataSource = this.trackBinder_;

                txtTagTrackName.DataBindinds.Add(new Binding("Text", this.trackBinder_, "TagTrackName"));
                txtTagArtist.DataBindings.Add(new Binding("Text", this.trackBinder_, "TagArtist"));
                txtTagTrackArtist.DataBindings.Add(new Binding("Text", this.trackBinder_, "TagTrackArtist"));
                ...

Gruß und danke für eure Beteiligung!
atmosfear

06.02.2009 - 22:04 Uhr

Noch ein Versuch:

dgridAlbum.DataSource = this.albums_;
dgridTrack.DataBindings.Add(new Binding("DataSource", this.albums_, "Tracks", true, DataSourceUpdateMode.OnPropertyChanged));

txtTagTrackName.DataBindings.Add(new Binding("Text", dgridTrack.DataSource, "TagTrackName"));
txtTagArtist.DataBindings.Add(new Binding("Text", dgridTrack.DataSource, "TagArtist"));

Jetzt funktioniert das Navigieren im Trackgrid beim ERSTEN Album, dann nicht mehr.
Sobald ich also im linken Grid ein anderes Album wähle und mich dann innerhalb der Track rechts bewege, wird die Textbox nicht mehr aktualisiert!?

DANKE
atmosfear

06.02.2009 - 21:53 Uhr

Hallo noch einmal!

Also ich habe jetzt Folgendes:

dgridAlbum.DataSource = this.albums_;
dgridTrack.DataBindings.Add(new Binding("DataSource", this.albums_, "Tracks", true, DataSourceUpdateMode.OnPropertyChanged));

this.bSourceTracks_ = new BindingSource(this.albums_, "Tracks");

txtTagTrackName.DataBindings.Add(new Binding("Text", this.bSourceTracks_, "TagTrackName"));
txtTagArtist.DataBindings.Add(new Binding("Text", this.bSourceTracks_, "TagArtist"));

Und es funktioniert NICHT!

DANKE
atmosfear

06.02.2009 - 21:49 Uhr

Hallo!

Du meinst wohl eher

txtTagArtist.DataBindings.Add(new Binding("Text", this.albums_, "Tracks", true, DataSourceUpdateMode.OnPropertyChanged));

anstatt

dgridTrack.DataBindings.Add("DataSource", this.albums_, "Tracks", true, DataSourceUpdateMode.OnPropertyChanged);

Die Eigenschaft "DataSource" wird die Textbox nicht unterstützen?!

Leider bekomme ich jetzt in der Textbox immer nur "(Auflistung)" angezeigt?

DANKE
atmosfear

!!!!!! EDIT: Sorry hab mich verlesen!!!!!!!
Ich probier's gleich noch einmal....

06.02.2009 - 21:37 Uhr

Hallo und einen schönen Abend zusammen!

Ich bin mit meinem Projekt noch schon ziemlich weit, allerdings nervt mich die Anbindung einer Textbox an die Property einer Klasse.

Hier mein Code:


    ...
    ...
    public class Album
    {
        private string artist_;
        private string albumName_;
        private string year_;
        private bool isCompilation_;
        private List<Track> tracks_;
        ...
        ...
        public List<Track> Tracks
        {
            get { return this.tracks_; }
        }
    }
    public class Track
    {
        private string trackNr_;
        private string trackArtist_;
        private string trackName_;
        private string trackExt_;

        private string tagTrackNr_;
        private string tagArtist_;
        private string tagTrackName_;

        private bool mismatch_;

        public string TagArtist
        {
            get { return this.tagArtist_; }
        }
    ...
    ...
                dgridAlbum.DataSource = this.albums_;
                dgridTrack.DataBindings.Add(new Binding("DataSource", this.albums_, "Tracks"));

                this.bSourceTracks_ = new BindingSource(this.albums_, "Tracks");

                //txtTagTrackName.DataBindings.Add("Text", this.albums_, "Track.TagTrackName");
                txtTagArtist.DataBindings.Add("Text", this.bSourceTracks_, "TagArtist");
        
     ....
     ....

Wenn ich im linken DataGridView navigiere dann bekomme ich im rechten Grid die Tracks des gewählten Albums - PASST.
Wenn ich aber innerhalb der Tracks navigiere, dann möchte ich die Textbox aktualisieren - Das passiert aber nicht!
Die Textbox hat immer den Wert des ersten Tracks und ändert sich danach nicht mehr?!

Kann mich jemand helfen oder einen Tipp geben?

DANKE
atmosfear

06.02.2009 - 19:11 Uhr

Hab's gerade herausgefunden!
Ich muss natürlich "BackColor" anstatt "SelectionBackColor" verwenden!

DANKE
atmosfear

06.02.2009 - 18:52 Uhr

Hallo!

Habe das Problem nun lösen können!
Das ganze funktioniert mittels eines DataBindings.

Für die jenigen die sich für meine Lösung interessieren, bitte sehr 😃

                dgridAlbum.DataSource = this.albums_;
                dgridTrack.DataBindings.Add("DataSource", this.albums_, "Track");

Dann klappt auch der Verweis auf die "Subklasse" Tracks (Klassendefinitionen siehen weiter oben)

Gruß
atmosfear

06.02.2009 - 18:47 Uhr

Hallo und schönen Abend zusammen!

Ich versuche mit folgendem Code einzelne Zeilen meines DataGridViews einzufärben.
Leider ohne Erfolg - es passierts nicht!?!?

        private void dgridAlbum_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            if ((e.RowIndex < 0)) return;
            Album album = dgridAlbum.Rows[e.RowIndex].DataBoundItem as Album;
            if (album.IsCompilation)
                dgridAlbum.Rows[e.RowIndex].DefaultCellStyle.SelectionBackColor = Color.FromArgb(128, 128, 128);
        }

Hat jemand eine Idee und/oder einen Tipp für mich?

DANKE
atmosfear

04.02.2009 - 15:24 Uhr

@schaedld
Danke für den Tipp und den Link!

@Th69
Wie soll das denn gehen?
albums_ ist eine Liste und hat keine Properties!
Nur die einzelnen Objekte der Liste hätten eine Property - nur wie soll ich auf die kommen?

atmosfear

04.02.2009 - 08:35 Uhr

Hallo und schönen guten Morgen zusammen!

Ich habe ein seltsames Problem, das ich nicht lösen kann.
Hier mein Quellcode:

...
...
...
        private BindingSource albumBinder_ = null;
        private BindingSource trackBinder_ = null;
        
        private List<Album> albums_ = new List<Album>();

        public frmMain()
        {
            InitializeComponent();

            dgridAlbum.AutoGenerateColumns = false;
            //dgridTrack.AutoGenerateColumns = true;
            dgridTrack.AutoGenerateColumns = false;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            this.albumBinder_ = new BindingSource(typeof(Album), "");
            this.trackBinder_ = new BindingSource(this.albumBinder_, "Track");

            dgridAlbum.DataSource = this.albumBinder_;
            dgridTrack.DataSource = this.trackBinder_;

            // albums
            DataGridViewColumn colArtist = new DataGridViewTextBoxColumn();
            colArtist.DataPropertyName = "Artist";
            colArtist.Name = "Artist";
            colArtist.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            colArtist.FillWeight = 50;
            dgridAlbum.Columns.Add(colArtist);

            DataGridViewColumn colAlbum = new DataGridViewTextBoxColumn();
            colAlbum.DataPropertyName = "AlbumName";
            colAlbum.Name = "Album";
            colAlbum.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            colAlbum.FillWeight = 50;
            dgridAlbum.Columns.Add(colAlbum);

            DataGridViewColumn colYear = new DataGridViewTextBoxColumn();
            colYear.DataPropertyName = "Year";
            colYear.Name = "Year";
            colYear.Width = 50;
            colYear.Resizable = DataGridViewTriState.False;
            dgridAlbum.Columns.Add(colYear);

            // tracks
            DataGridViewColumn colTrackNr = new DataGridViewColumn();
            colTrackNr.DataPropertyName = "TrackNr";
            colTrackNr.Name = "TrackNr";
            dgridTrack.Columns.Add(colTrackNr);

            DataGridViewColumn colTrackName = new DataGridViewColumn();
            colTrackName.DataPropertyName = "TrackName";
            colTrackName.Name = "TrackName";
            dgridTrack.Columns.Add(colTrackName);
        }
...
...

TrackNr und TrackName sind jeweils public Properties der Klasse Track
Auch hier der Quelltext:

...
...
    public class Album
    {
        private string artist_ = String.Empty;
        private string albumName_ = String.Empty;
        private string year_ = String.Empty;
        private List<Track> track_ = null;

        public Album(string artist, string albumName, string year)
        {
            this.artist_ = artist;
            this.albumName_ = albumName;
            this.year_ = year;
            this.track_ = new List<Track>();
        }

        public Album(string artist, string albumName, string year, List<Track> track)
        {
            this.artist_ = artist;
            this.albumName_ = albumName;
            this.year_ = year;
            this.track_ = track;
        }
        
        public string Artist
        {
            get { return this.artist_; }
        }

        public string AlbumName
        {
            get { return this.albumName_; }
        }

        public string Year
        {
            get { return this.year_; }
        }

        public List<Track> Track
        {
            get { return this.track_; }
        }

        public void AddTrack(Track track)
        {
            this.track_.Add(track);
        }
    }
...
...
    public class Track
    {
        private string trackNr_ = String.Empty;
        private string trackName_ = String.Empty;

        public Track(string trackNr, string trackName)
        {
            this.trackNr_ = trackNr;
            this.trackName_ = trackName;
        }

        public string TrackNr
        {
            get { return this.trackNr_; }
        }

        public string TrackName
        {
            get { return this.trackName_; }
        }
    }
...
...

Das eigentlich Interessante an diesem Beispiel ist, dass wenn ich AutoGenerateColumns auf true setze, die Daten im rechten Grid (dem Trackgrid) angezeigt werden. Wenn ich die einzelnen Spalten aber mit oben gezeigtem Code selbst generiere, sehe ich keine Daten.

Ich habe gelesen, dass die "DatePropertyName" Eigenschaft einer DataGridViewColumn nicht mit "nested" Objekten einer Klasse zurechtkommt.
Dinge wie "Klasse.Property" funktionieren ja nicht!

Wie macht das .NET aber im Hintergrund - ich meine, wenn ich AutoGenerateColumns arbeite funktioniert es ja auch?!

Ich weiss echt nicht mehr weiter und wäre über jeden Tipp eurerseits sehr dankbar!

DANKE
atmosfear

03.02.2009 - 19:21 Uhr

Hallo Th69,

Danke für deine Antwort!
Ja, ich möchte im zweiten Grid nur die Tracks darstellen die dem jeweilig selektierten Album entsprechen!
Ich habe das schon einige Male mit Datasets und Datatables gemacht, aber noch nie mit
nur einer generischen Liste!

Ich weiss nicht, wie die DataPropertyName der entsprechenden GridColumn gesetzt werden muss?!

DANKE
atmosfear

31.01.2009 - 12:41 Uhr

Hallo und Mahlzeit zusammen!

Ich habe ein Problem bei der Anbindung zweier DatagridViews an eine generische Liste.
Ich rede nicht lange um den Brei herum, sondern zeige euch gleich den Quellcode.


    public class Album
    {
        private string artist_;
        private string albumName_;
        private string year_;
        private List<Track> track_ = new List<Track>();

        public Album(string artist, string albumName, string year)
        {
            this.artist_ = artist;
            this.albumName_ = albumName;
            this.year_ = year;
        }
        ...
        ...
        public List<Track> Track
        {
            get { return this.track_; }
        }
        
        public void AddTrack(Track track)
        {
            this.track_.Add(track);
        }
   }

    public class Track
    {
        private string trackNr_;
        private string trackName_;

        public Track(string trackNr, string trackName)
        {
            this.trackNr_ = trackNr;
            this.trackName_ = trackName;
        }

        public string TrackNr
        {
            get { return this.trackNr_; }
        }

        public string TrackName
        {
            get { return this.trackName_; }
        }
    }

    ...
    ...
    ...

    public partial class frmMain : Form
    {
        private string statusMessage_ = String.Empty;
        private List<Album> folderAlbums_ = new List<Album>();

        public frmMain()
        {
            InitializeComponent();

            dgridAlbum.AutoGenerateColumns = false;
            dgridTrack.AutoGenerateColumns = false;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            DataGridViewColumn colArtist = new DataGridViewTextBoxColumn();
            colArtist.DataPropertyName = "Artist";
            colArtist.Name = "Artist";
            dgridAlbum.Columns.Add(colArtist);

            DataGridViewColumn colAlbum = new DataGridViewTextBoxColumn();
            colAlbum.DataPropertyName = "AlbumName";
            colAlbum.Name = "Album";
            dgridAlbum.Columns.Add(colAlbum);

            DataGridViewColumn colYear = new DataGridViewTextBoxColumn();
            colYear.DataPropertyName = "Year";
            colYear.Name = "Year";
            dgridAlbum.Columns.Add(colYear);

            DataGridViewColumn colTrackNr = new DataGridViewColumn();
            colTrackNr.DataPropertyName = "Track"; // ??????
            colTrackNr.Name = "Track";
            dgridTrack.Columns.Add(colTrackNr);
        }

        private void btnTagLib_Click(object sender, EventArgs e)
        {
            ...
            ...
            // create new album object
            Album newAlbum = new Album(artist, album, year);
            ...
            ...
            Track newTrack = new Track(trackNr, trackTitle);
            newAlbum.AddTrack(newTrack);
            ...
            ...
            folderAlbums_.Add(newAlbum);
            ...
            ...
            dgridAlbum.DataSource = null;
            dgridAlbum.Refresh();

            dgridAlbum.DataSource = folderAlbums_;
            dgridAlbum.Refresh();

            dgridTrack.DataSource = null;
            dgridTrack.Refresh();

            dgridTrack.DataSource = folderAlbums_; // ?????
            dgridTrack.Refresh();
       }
   }   

Wie man sieht habe ich eine Klasse "Album" die eine generische Liste für die Tracks beinhaltet, die vom Typ "Track" ist. Track ist wiederum eine Klasse die Eigenschaften eines MP3 Tracks verwaltet.

Ich möchte in einem DatagridView eine Liste von Alben darstellen und in dem Grid daneben eine Liste mit den dazugehörigen Tracks.
Das erste Grid wurde an die Liste "folderAlbums_" gebunden, das funktioniert auch.
Aber woran muss ich das zweite Grid binden?

Danke
atmosfear

EDIT: Sorry! Habe die Korrekturen vorgenommen!

25.01.2009 - 19:36 Uhr

Hallo winSharp93!

Also ich versuche Folgendes:
Ich habe ein CSV File mit allen Dateien, z.B.:

AC-DC;Back In Black;1;1980;M:\Hard & Heavy\AC-DC - Back In Black (1980)\;01 Hells Bells.mp3
AC-DC;Back In Black;2;1980;M:\Hard & Heavy\AC-DC - Back In Black (1980)\;02 Shoot To Thrill.mp3
...
...

Diese Daten lese ich in eine generische Liste von Objekten vom Typ album ein (siehe Klasse Album oben)

Nun hole ich mir alle Verzeichnisse meiner Musiksammlung. Diese habe ich in einem String Array abgelegt (also die Verzeichnisnamen)

Ich möchte wissen, ob es Alben gibt, die zwar von einem unterschiedlichen Interpreten sind, aber den gleichen Albumnamen besitzen.

Wie soll ich hier am besten vorgehen?
Ich nehme mal an, dass ich 2 Schleifen brauche.
Die äußere iteriert durch alle Album Objekte und die innere durch alle Verzeichnisse aus dem String Array.
Dor muss ich prüfen ob ich ein Album finde, das den gleichen Namen wie der rechte Teil des Verzeichnisses hat und zusätzlich prüfe ich noch ob der der Albumname auch in einem anderen Verzeichnis vorkommt.
Kompliziert zu erklären finde ich....

Der Code:


            foreach (Album album in album_)
            {
                // bei albumdirectories müsste noch der pfad abgeschnitten werden, um nur den albumnamen zu erhalten?
                foreach (string dir in albumdirectories)
                {
                   List<Album> result = album_.FindAll(delegate(Album a) { return String.Equals(a.AlbumName, ?????); });
                   ????
                   // prüfung ob der AlbumName in mehreren Verzeichnissen vorkommt
                }
            }

DANKE
atmosfear

25.01.2009 - 19:17 Uhr

Hallo und schönen Abend zusammen!

Ich suche nach einer Möglichkeit einen Vergleich zwischen einem String und einer Public Property einer generischen Liste zu machen.

Stellt euch das Ganze folgendermassen vor:

private List<Album> album_ = new List<Album>();
...
...
...
            int lineIdx = 0;
            
            StreamReader reader = new StreamReader(@"T:\hardheavy.csv", Encoding.Default);
            do
            {
                // read current line
                string actLine = reader.ReadLine();
                if (lineIdx > 0)
                {
                    string[] splitLine = actLine.Split(';');
                    if (splitLine.Length == 6)
                    {
                        album_.Add(new Album(splitLine[0], splitLine[1], splitLine[2], splitLine[3], splitLine[4], splitLine[5]));
                    }
                }
                lineIdx++;

            } while (reader.Peek() != -1);

            // close reader
            reader.Close();

            // check for equal album names
            foreach (Album album in album_)
            {
                ???
            }
...
...
...
public class Album
    {
        private string artist_;
        private string albumName_;
        private string track_;
        private string year_;
        private string path_;
        private string fileName_;

        public Album(string artist, string albumName, string track, string year, string path, string fileName)
        {
            this.artist_ = artist;
            this.albumName_ = albumName;
            this.track_ = track;
            this.year_ = year;
            this.path_ = path;
            this.fileName_ = fileName;
        }

        public string Artist
        {
            get { return this.artist_; }
        }

        public string AlbumName
        {
            get { return this.albumName_; }
        }
   }

Ich habe ein string Array mit Verzeichnisnamen. Diese möchte ich durchlaufen und wissen, ob in meiner Liste ein Objekt ist, dass dem Eintrag entspricht.
Der Name des Verzeichnisses sollte also mit der Public Property "AlbumName" des aktuellen Objekts album_ verglichen werden.

Ich kenne die FindIndex und die Contains Methode der List-Klasse, aber wie muss der Delegate (Predicate) dazu aussehen?

DANKE
atmosfear

25.01.2009 - 14:45 Uhr

Hallo JunkyXL,

ja, mit Contains funktioniert's!?!?!?!?!?
Keine Ahnung warum, aber es geht...

DANKE
atmosfear

25.01.2009 - 14:15 Uhr

Hallo und schönen Nachmittag zusammen!

Ich schreibe mir gerade ein kleines Tool, das mir die Einträge einer m3u Playlist mit den Unterverzeichnissen eines Verzeichnisses vergleich
und damit prüft, ob alle Verzeichnisse in der Playlist vorhanden sind.

Als erstes lese ich also die Playlist aus und speichere alle Einträge in einer <List>string.
Dann hole ich mir alle Verzeichnisse meines Ausgangsverzeichnisses und überprüfe ob das Verzeichnis in meiner Liste gefunden wirde.
Leider funktioniert das nicht - der 2te FindIndex liefert immer 0, obwohl die beiden String absolut ident sind!?!?!?

Hier mein Quelltext

            List<string> playlistFolders = new List<string>();
            List<string> folderNotInPlaylist = new List<string>();

            char[] charsToTrim = { '\\' };
            
            // get all entries from playlist
            StreamReader reader = new StreamReader(@"T:\hardheavy.m3u");
            do
            {
                // read current line
                string actLine = reader.ReadLine();
                if (!actLine.StartsWith("#"))
                {
                    int lastBackslash = actLine.LastIndexOf(@"\");
                    // get last backslash to remove the filename
                    // d:\directory\01 track.mp3 ==> d:\directory
                    if (lastBackslash > -1)
                    {
                        actLine = actLine.Remove(lastBackslash);
                        // check if element is already in the list
                        int listEntry = playlistFolders.FindIndex(delegate(string arg) { return (arg.Equals(actLine)); });
                        if (listEntry == -1)
                            playlistFolders.Add(actLine);
                    }
                }
            } while (reader.Peek() != -1);

            // close reader
            reader.Close();

            // now comare all entries with all directories
            string[] folders = Directory.GetDirectories(@"M:\Hard & Heavy\", "*", SearchOption.AllDirectories);
            foreach (string actFolder in folders)
            {
                int listEntry = playlistFolders.FindIndex(delegate(string arg) { return (arg.Equals(actFolder)); });
                if (listEntry != -1)
                    folderNotInPlaylist.Add(actFolder);
            }

            foreach (string folder in folderNotInPlaylist)
            {
                MessageBox.Show(folder);
            }

Vielen Dank für eure Hilfe!
atmosfear

10.07.2008 - 10:38 Uhr

Hallo herbivore,

hier meine fertige Lösung:

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = this.Controls.Count - 1; i > 0; i--)
            {
                if (this.Controls[i] is Label && (this.Controls[i].Name.StartsWith("klbl") || this.Controls[i].Name.StartsWith("ktlbl")))
                    this.Controls.RemoveAt(i);
            }
            
            Regex keywordRegex = new Regex(@"(?<keyword>\%[^\%]+\%)(?<seperator>[^\%]*)");
            MatchCollection keywords = keywordRegex.Matches(this.textBox1.Text.ToString());

            string dynPattern = String.Empty;
            foreach (Match match in keywords)
            {
                string keyword = match.Groups["keyword"].Value.Replace("%", "");
                string seperator = match.Groups["seperator"].Value.Replace("(", "\\(");
                seperator = seperator.Replace(")", "\\)");
                
                dynPattern = dynPattern + "(?<" + keyword + ">.*)" + seperator;
            }

            Regex dynamicRegex = new Regex(dynPattern);
            Match sourceMatch = dynamicRegex.Match(this.textBox2.Text.ToString());

            int diffY = 0;
            foreach (Match match in keywords)
            {
                string keyword = match.Groups["keyword"].Value.Replace("%", "");
                Group group = sourceMatch.Groups[keyword];
                
                Label label = new Label();
                label.Name = "klbl" + keyword;
                label.Text = keyword;
                label.Location = new Point(32, 72 + diffY);
                label.MaximumSize = new Size(50, 13);
                label.BackColor = Color.Aqua;
                this.Controls.Add(label);

                Label textLabel = new Label();
                textLabel.Name = "ktlbl" + group.Value;
                textLabel.Text = group.Value;
                textLabel.Location = new Point(82, 72 + diffY);
                textLabel.MaximumSize = new Size(200, 13);
                textLabel.BackColor = Color.BurlyWood;
                this.Controls.Add(textLabel);
                
                diffY += 20;
            }
        }

DANKE und Gruß an alle!
atmosfear

10.07.2008 - 10:03 Uhr

Hallo nochmal!

Ich habe mir jetzt Folgendes zurechtgelegt und ich denke es sieht nicht schlecht aus:

            Regex keywordRegex = new Regex(@"(?<keyword>\%[^\%]+\%)(?<seperator>[^\%]*)");
            MatchCollection keywords = keywordRegex.Matches(this.textBox1.Text.ToString());

            Regex dynamicRegex = new Regex(@"(?<artist>.*) - (?<title>.*) \((?<year>.*)\)");
            Match sourceMatch = dynamicRegex.Match(this.textBox2.Text.ToString());

DANKE
atmosfear

10.07.2008 - 09:34 Uhr

Hallo herbivore,

Ahhhh, mein Fehler!!! Ich hatte anstatt

Match newkey = test.Match(this.textBox2.Text.ToString());
Match newkey = test.Match(this.textBox2.ToString());

verwendet.... 👅

Genauso, wie du an den die anderen Informationen kommst, nämlich in dem du die entsprechenden Abschnitte des Patterns in Gruppen (runden Klammern) einschließt.

Sorry, aber da da kann ich dir nicht folgen...

DANKE
atmosfear

10.07.2008 - 09:11 Uhr

Hallo und schönen Morgen zusammen!

Vorweg einmal: VIELEN DANK für eure Antworten!

Leider stehe ich aber irgendwie auf der Leitung 🤔
Also, ich habe nun Folgendes:

            Regex test = new Regex(@"(?<artist>.*) - (?<title>.*) \((?<year>.*)\)");
            Match newkey = test.Match(this.textBox2.ToString());

Der Inhalt von textBox2 ist

Testartist - Testalbum (Testyear)

Das Ergebnis laut Debugger ist ein wenig seltsam:

+		newkey.Groups[0]	{System.Windows.Forms.TextBox, Text: TestArtist - TestAlbum (TestYear)}	System.Text.RegularExpressions.Group {System.Text.RegularExpressions.Match}
+		newkey.Groups[1]	{System.Windows.Forms.TextBox, Text: TestArtist}	System.Text.RegularExpressions.Group
+		newkey.Groups[2]	{TestAlbum}	System.Text.RegularExpressions.Group
+		newkey.Groups[3]	{TestYear}	System.Text.RegularExpressions.Group

Was ich vor allem nicht ganz verstehe ist die Tatsache, dass der Albumname und das Jahr richtig 'geparst' werden, der Interpret aber nicht!?

EDIT:
Ausserdem muss ich den Formatstring (also den Regex Pattern) ja dynamisch generiere, da dieser vom User eingegeben werden kann.
Dazu brauche ich aber nicht nur dir einzelnen Keywords (artist, album. ....) sondern auch die Trennzeichen dazwischen.
Wie komme ich mittels einer Regex am besten zu diesen?

DANKE für eure Hilfe!
atmosfear

09.07.2008 - 14:59 Uhr

@Khalid,

ich habe nun die einzelnen Keywords extrahiert:

            Regex regex = new Regex(@"\%[^\%]+\%");
            MatchCollection keywords = regex.Matches(this.textBox1.ToString());

Ich brauche aber zusätzlich die Trennzeichen, oder?
Denn der Quellstring soll ja auch dynamisch sein, also muss nicht immer im Format
Interpret - Titel (Jahr)
daherkommen...

DANKE
atmosfear

09.07.2008 - 14:13 Uhr

Hallo und Mahlzeit!

@trib
Danke für die Antwort - leider ist dein Ansatz nicht dynamisch, da du auf fixes Muster losgehst...

@Khalid
Ja, an RegEx hatte ich auch schon gedacht - ich brauche ja aber auch die Trennzeichen und nicht nur die Keywords des Suchmusters!

Wenn ich mir z.B.: aus dem Suchmuster zuerst die Keywords mittels RegEx heraushole, dann weiss ich nur die Keywords und nicht, wie ich den Quellstring teilen/splitten muss,
um an die richtigen Infos zu kommen. Oder liege ich da falsch?

EDIT:
Und vor allem: Wie die einzelnen Keywords mittels Regex auf dem Suchmuster extrahieren?

Danke
atmosfear

09.07.2008 - 08:43 Uhr

Hallo und guten Morgen allerseits!

Ich versuche ein Verzeichnis mit einem bestimmten, frei wählbaren Formatstring zu zerlegen.
Wenn ich z.B.: das Verzeichnis "Interpret - Titel (Jahr)" als Ausgangspunkt nehme, dann soll ich mit dem Formatstring %artist% - %title% (%year%) den Verzeichnisnamen in die Einzelteile zerlegen können.

Ich habe das folgendermassen gelöst, bin aber noch nicht ganz glücklich damit:

Zuerst hole ich mir alle Keywords in die Liste keywords (Anfangs- und End % suchen, usw.)
In diesem Zuge hole ich mir auch noch gleich die Trennzeichen in die Liste seperators.
Anschliessend extrahiere ich an Hand der Trennzeichen den Quellstring und erstelle dynamische Labels um das Ergebnis darstellen zu können.

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = this.Controls.Count - 1; i > 0; i--)
            {
                if (this.Controls[i] is Label && (this.Controls[i].Name.StartsWith("klbl") || this.Controls[i].Name.StartsWith("ktlbl")))
                    this.Controls.RemoveAt(i);
            }
            
            string searchPattern = textBox1.Text.ToString();
            string tempSep = String.Empty;
            
            int bCount = 0;
            int bBegin = 0;
            int bEnd = 0;

            bool addNewSep = false;

            List<string> keywords = new List<string>();
            List<string> seperators = new List<string>();
            List<string> matches = new List<string>();
            
            // get all keywords and seperators
            for (int i = 0; i < searchPattern.Length; i++)
            {
                if (searchPattern[i] == '%')
                {
                    if (bCount < 1)
                    {
                        bCount++;
                        bBegin = i;
                        if (bEnd > 0)
                            addNewSep = true;
                    }
                    else
                    {
                        bCount = 0;
                        bEnd = i;
                        keywords.Add(searchPattern.Substring(bBegin + 1, bEnd - bBegin - 1));
                    }
                }
                else
                {
                    if (bCount < 1)
                        tempSep += searchPattern[i];
                }
                if (i == searchPattern.Length - 1)
                    addNewSep = true;

                if (addNewSep && (!String.IsNullOrEmpty(tempSep)))
                {
                    seperators.Add(tempSep);
                    addNewSep = false;
                    tempSep = String.Empty;
                }

            }

            // split input string
            string temp = this.textBox2.Text.ToString();
            foreach (string seperator in seperators)
            {
                int startIdx = temp.IndexOf(seperator);
                if (startIdx > -1)
                {
                    matches.Add(temp.Substring(0, startIdx));
                    temp = temp.Substring(startIdx + seperator.Length);
                }
            }
            
            // display all keywords and matches
            int diffY = 0;
            for (int i = 0; i < keywords.Count; i++)
            {
                Label label = new Label();
                label.Name = "klbl" + keywords[i];
                label.Text = keywords[i];
                label.Location = new Point(32, 72 + diffY);
                label.MaximumSize = new Size(50, 13);
                label.BackColor = Color.Aqua;
                this.Controls.Add(label);

                if (matches.Count > i)
                {
                    Label textLabel = new Label();
                    textLabel.Name = "ktlbl" + matches[i];
                    textLabel.Text = matches[i];
                    textLabel.Location = new Point(82, 72 + diffY);
                    textLabel.MaximumSize = new Size(200, 13);
                    textLabel.BackColor = Color.BurlyWood;
                    this.Controls.Add(textLabel);
                }
                
                diffY += 20;
            }
        }

Ich wollte euch deshalb fragen ob ihr andere Vorschläge habt bzw. ob ich das Problem auf eine andere Art und Weise lösen soll/kann.

Würde mich über eure Verbesserungsvorschläge sehr freuen und wünsche einen schönen Vormittag!

atmosfear

14.05.2008 - 08:14 Uhr

Vielen DANK für deine Antwort!

Zur Info - ich hab's jetzt so gemacht:

        private static string VersionNr()
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            AssemblyName asmName = asm.GetName();

            object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
            string productName = String.Empty;

            if (attribs.Length > 0)
            {
                AssemblyProductAttribute asmProduct = attribs[0] as AssemblyProductAttribute;
                productName = asmProduct.Product.ToString();
            }

            string vers = String.Format("{0} - Version: {1}.{2}.{3} Build: {4}",
                productName,
                asmName.Version.Major.ToString(),
                asmName.Version.Minor.ToString(),
                asmName.Version.Build.ToString(),
                asmName.Version.Revision.ToString());

            return (vers);
        }

Gruß
atmosfear