Laden...

Forenbeiträge von Rainer Wein Ingesamt 90 Beiträge

06.08.2016 - 12:15 Uhr

Hallo zusammen,

ich schreibe mir gerade eine kleine Anwendung in der ich das DataGridView-Steuerelement verwende um Daten anzuzeigen, zu filtern und zu sortieren.
Dabei habe ich jedoch folgendes Problem. Entweder es funktioniert die Datensortierung oder die Datenfilterung, aber nicht beides.

Verwende ich eine DataTable und übergebe sie dem DataGridView als DataSource funktioniert die Datenfilterung einwandfrei:

(entrys_DGV.DataSource as DataTable).DefaultView.RowFilter = String.Format("Text LIKE '{0}'", search_TB.Text);

Die Datensortierung (Alphabetisch) ist dagegen suboptimal. Sobald ich eine Zelle bearbeite wird diese aufgrund der Sortierung automatisch
an die "richtige" Position verschoben. Ich hätte es aber gern das erst beim erneuten Klick auf die Spalte die Daten neu sortiert werden.

Ich habe das Programm anschließend umgebaut um dieses Problem zu lösen. Dem DataGridView werden nun die Daten manuell hinzugefügt und ein eigener RowComparer verwendet.

 
entrys_DGV.Columns.Add("Text", "Text-Spalte");
entrys_DGV.Columns[3].ValueType = typeof(String);
entrys_DGV.Columns[3].SortMode = DataGridViewColumnSortMode.Programmatic;

foreach (DataRow row in strEntrys.Rows)
   {
      DataGridViewRow newRow = new DataGridViewRow();
      newRow.CreateCells(this.entrys_DGV);
      newRow.Cells[0].Value = row[0];
      entrys_DGV.Rows.Add(newRow);
    }

Damit funktioniert zwar die Datensortierung wie gewünscht aber natürlich nicht mehr die Datenfilterung.
Kennt jemand eine Möglichkeit mit der man beide Anforderungen, ohne viel Aufwand, umsetzen kann?

08.06.2014 - 17:24 Uhr

Vielen Dank erstmal für den Hinweis trotzdem ist mir nicht ganz klar wie ich jetzt vorgehen muss.

Es geht um ein eigenes Steuerelement.
Das Panel(ClientRec) besitzt als BorderStyle den Type Fixed3D. Das Panel soll nun in weitere Bereiche unterteilt werden.
Als Beispiel soll die vom ClientRec zur Verfügung gestellt Fläche abzüglich der Border nochmal als eine gesonderte Fläche (ContentRec) unterteilt werden (Rot dargestellt).

<siehe Anhang>

Im Code sieht dies so aus:



ContentRec = ClientRec;

ContentRec .X += BorderLeft;
ContentRec .Y += BorderTop;
ContentRec .Width -= BorderRight + BorderLeft;
ContentRec .Height -= BorderBottom + BorderTop;


Hätte ich damit die komplette Fläche des ClientRec erfasst?
Zur Überprüfung der Größe hatte ich ein farbiges Rechteck gezeichnet welches wie bereits erwähnt immer ein Pixel zu lang war und damit die Border überzeichnet hatte.

08.06.2014 - 16:21 Uhr

Hallo zusammen.

Auch auf die Gefahr hin mich lächerlich zu machen, ich habe ein Problem beim Zeichenen eines Rechteckes auf einem Panel.


using (Graphics g = this.panel1.CreateGraphics())
{
      Pen pen = new Pen(Color.Black, 1F);
      pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;

      g.DrawRectangle(pen, 2, 2, 10 , 10);
}

Wie man anhand meines Codes erkennen kann, soll ein Rechteck von 1010 Pixel an der Position 2,2 gezeichnet werden. Schaut man sich aber das gezeichnete Rechteck in einem Zeichenprogramm an
<siehe Anhang>
sieht man das das Rechteck zwar an der Position 2,2 gezeichnet wurde aber keine 10
10 Pixel groß ist. Warum?

10.09.2013 - 14:59 Uhr

Vielen Dank erst einmal für die Vorschläge.

Zum Thema "Verzögertes Laden von Daten im TreeView" habe ich bedenken, da ich zuvor trotzdem alle Dateien durchlaufen muss um die Ordner-Struktur zu erstellen auch wenn ich zuerst nur die oberste Ebene benötige. Wird dann ein Knoten aufgeklappt, muss ich das ganze wieder durchlaufen. Ich werde es mir trotzdem noch einmal anschauen.

Es wird zwar insgesamt langsamer, aber das Benutzerinterface bliebe dafür ansprechbar. Das ist ja dein Ziel wenn ich es richtig verstanden hab.

Danke für die Bestätigung, testen werde ich trotzdem einmal, vielleicht sind die Auswirkungen ja nicht so gravierend.

Ich hatte vorhin noch eine Idee, vielleicht kann jemand etwas dazu sagen.
Ich erstelle ein HashSet<String> in der nur die Pfade der Ordner zu finden sind. Diese lasse ich dann ganz normal über meine Methode erzeugen. Anschließend durchlaufe ich die Dateien noch einmal und füge die entsprechenden Dateien den Ordnern hinzu. Die hätte theoretisch den Vorteil das ich nicht ständig den Baum durchlaufen müsste. Setzt natürlich voraus dass es eine Möglichkeit gibt ein Node an einer bestimmten Stelle (Pfad) einzufügen.

10.09.2013 - 12:33 Uhr

Hallo zusammen,
ich nutze einen TreeView um die Verzeichnisstruktur einer Archiv-Datei darzustellen. Beim Füllen des TreeViews blockiert jedoch die GUI, da der Vorgang zu lang dauert. Um das blockieren zu vermeiden, wollte ich eigentlich einen BackgroundWorker nutzen. Laut einigen Forenbeiträgen sollte man dies aber nicht unbedingt tun, da man beim Hinzufügen der Nodes jedes Mal Invoken muss und dies den Füllvorgang ausbremsen soll.

Meine Frage ist nun, ob es eine andere Möglichkeit als den Backgroudworker gibt oder ob die Methode optimiert werden kann um ganz darauf zu verzichten? Dazu noch eine kurze Erklärung: Jeder entry repräsentiert eine Datei, die einen String mit der Angabe zum Verzeichnis enthält. Mithilfe der Methode addNodeWithPath() durchsuche ich den Baum rekursiv und prüfe ob das angegebene Verzeichnis bereits existiert. Ist dies nicht der Fall wird erst das Verzeichnis-Node und dann die dazugehörige File-Node erstellt. Da es sich insgesamt um ca. 19000 Einträge handelt und ich bei jeder Datei diesen Vorgang wiederholen muss kann dies natürlich etwas dauern. Sieht jemand eine Möglichkeit diesen Vorgang zu beschleunigen?


public void generateTreeView()
{
      this.file_TREE.BeginUpdate();
      TreeNode folderNode = null;
      TreeNode fileNode = null;
      LsrFile file = null;
   
      for (int i = 0; i < LsrManager.GetFiles().Count; i++)
      {
          file = LsrManager.GetFiles()[i];
          foreach (LsrEntry entry in file.EntryList)
          {
              folderNode = addNodeWithPath(file_TREE.Nodes, entry.DirName);

              fileNode = new TreeNode();
              fileNode.Text = entry.FileName;
              fileNode.Tag = entry;

              if (folderNode != null)
              {
                  folderNode.Nodes.Add(fileNode);
              }
              else
              {
                  file_TREE.Nodes.Add(fileNode);
              }
          }
      }

      this.file_TREE.EndUpdate();
}


private TreeNode addNodeWithPath(TreeNodeCollection nodes, string path)
        {
            var leaf = System.IO.Path.GetFileName(path);

            if (path != leaf)
            {
                nodes = addNodeWithPath(nodes, System.IO.Path.GetDirectoryName(path)).Nodes;
            }

            var node = nodes.Find(leaf, false).FirstOrDefault();

            if (node == null)
            {
                if (leaf != String.Empty)
                {
                    node = nodes.Add(leaf, leaf);
                }
            }
            return node;
        }
01.09.2013 - 12:23 Uhr

Ok, jetzt muss ich hier doch noch einmal aufmachen. Mir ist gerade aufgefallen, dass meine Methode nicht funktioniert, wenn ich im TreeView eine Datei markiere und dann den Baum durchlaufe. Da die markierte Datei keine Childnodes besitzt, wird die for-each-Schleife übersprungen.
Ich hätte theoretisch noch die Möglichkeit einfach Abzufragen ob das Tag-Objekt des Nodes != null ist, da jede Datei-Node ein Tag Element besitzt.

Kann mir jemand einen Tipp geben wie man die Sache eleganter lösen kann?

30.08.2013 - 18:57 Uhr

Bei mir ist gerade jemand vorbeigelaufen und hat mir auf den Hinterkopf geschlagen.

Falls es jemanden interessiert, hier meine Lösung:


public void getFileNodes(List<TreeNode> fileNodes, TreeNode currentNode)
{

            foreach (TreeNode node in currentNode.Nodes)
            {
                if (node.Nodes.Count == 0)
                {
                    fileNodes.Add(node);
                }
                else
                {
                    getFileNodes(fileNodes, node);
                }

            }
}

30.08.2013 - 18:23 Uhr

Hallo Zusammen.

Ich stelle mithilfe eines TreeViews ein Dateisystem dar. Klickt ein Nutzer auf einen Knoten soll es möglich sein, alle enthaltene Datein zu speichern.

System

|
|- Folder1
|  |------ File1
|  |------ Folder2
|          |----- File2
|- File 3

Ich versuch also eine Liste mit allen Dateieinträgen zu erstellen. Durchlaufe ich einfach
den selektierten Knoten sind aber auch Ordner-Knoten enthalten. Gibt es eine Möglichkeit
wie ich nur die Knoten "File1","File2" und "File3"erhalte?

28.02.2013 - 14:46 Uhr

Vielen dank für den Vorschlag, ist leider c-code.
Gibt es ähnliche Bibliotheken für .NET?

28.02.2013 - 10:28 Uhr

Oh man,

natürlich war meine Recherche umfangreicher, hätte ich dabei eine adequate Lösung gefunden würde ich hier nicht um Hilfe bitten.

Angeschaut habe ich mir folgende:
Freeimage -> kann dds nur lesen
AForge -> kein dds support
DevIL .NET Wrapper -> Unterstützt kein Formate (DX1,DX2..) von dds
-> fehlerhaft unter .NET 4.0

Alle betrachteten Bibliotheken erfüllen leider nicht die gestellten Anforderungen.

27.02.2013 - 18:16 Uhr

Hallo zusammen,

ich bin auf der Suche nach einer Bibliothek die es mir ermöglich dds Dateien zu lesen bzw. zu schreiben. Konkret heißt das, ich möchte png sowie dds Dateien in einer PictureBox anzeigen, umwandeln (png<->dds) sowie speichern können. Außerdem soll die Bibliothek Informationen zum Format liefern können (Welches DDS-Format, Bildgröße...). Die Bildbearbeitung steht dabei nicht im Vordergrund.

Nach meiner Recherche ist dies wohl mit DirectX bzw. XNA möglich. Für meine Anforderungen scheint mir das ganze aber etwas über das Ziel hinaus zu gehen.

Grüße

05.04.2012 - 17:39 Uhr

Habe ich etwas übersehen?

Wenn ich die Datei mithilfe eines Filestreams öffne und dann einen BinaryWriter nutze, wird der Inhalt doch nur überschrieben, ich möchte aber Inhalt einfügen.

05.04.2012 - 16:23 Uhr

Hallo zusammen.

Ich möchte in eine BIN-Datei eine weitere Datei einfügen; die Einfügeposition spielt dabei eine Rolle.

Normalerweise, würde ich die BIN-Datei komplett einlesen, die neue Datei einfügen (Buffer.BlockCopy, Array.Copy) und anschließend die komplette Datei zurückschreiben.
Da die zu öffnende BIN-Datei aber bis zu 800MB groß ist und recht häufig Änderungen durchgeführt werden, erscheint mir die Lösung nicht optimal.

Gibt es alternative Lösungsmöglichkeiten, um nicht jedes Mal die BIN-Datei komplett neu zu schreiben?

Grüße Rainer

17.02.2012 - 12:22 Uhr

Danke für die Erläuterungen.

Ich werde weiterhin verschachtelte using-Anweisungen nutzen und nur im Notfall den Code umstellen.

Ohne den großen Überblick zu besitzen, frag ich mich weshalb die Dispos Methode nicht einfach Abfragt ob das Objekt null ist, dann wäre man ja fein raus.

16.02.2012 - 18:32 Uhr

Hallo zusammen,

ich habe eine Frage zu dem von Microsoft zur Verfügung gestellten Artikel CA2202: Objekte nicht mehrmals verwerfen.

Wenn die IDisposable-Ressource der geschachtelten inneren using-Anweisung die Ressource der äußeren using-Anweisung enthält, gibt die Dispose-Methode der geschachtelten Ressource die enthaltene Ressource frei.

Laut Artikel gibt die innere using-Anweisung die Ressource der äußeren Using-Anweisung mit frei.
Jetzt stellt sich mir die Frage, weshalb ich im finally-Block die Ressourcen explizit frei geben soll wenn dies die innere Using-Anweisung bereits tut.

08.02.2012 - 21:26 Uhr

Ich habe es nochmal skizziert um eventuelle Missverständnisse auszuräumen.

Mir stellt sich nun die Frage ob ich die Archiv-Datei im Speicher lassen soll oder besser nur die Namen der Archive auslese und diese in der ListBox1 anzeige. Das heißt jedesmal wenn der Anwender ein Element aus der ListBox1 auswählt, müßte ich die Archiv-Datei erneut öffnen.
Da wie bereits erwähnt die Archiv-Datei bis zu 800MB groß sein kann, ist es mir wichtig die Arbeitsspeicherauslastung gering zu halten und dennoch eine vernüftige Geschwindigkeit für die Anzeige zu erreichen.

Um was für ein Archivierungssystem handelt es sich?
Etwas Selbstgeschriebenes?
Oder etwas wie NFileStorage? Oder schlichtweg Zip?

Es handelt sich um das Afs-Format

08.02.2012 - 20:04 Uhr

Ich würde die nicht offen lassen. Warum denn auch?

Das heißt, ich sollte die im Archiv befindlichen Dateien (Name + Offset + Length) auslesen und diese in der Listbox anzeigen. Erst wenn der Nutzer einen Eintrag aus der ListBox ausgewählt, öffne ich das Archiv erneut und entpacke die Daten?

Was meinst du mit gegebenenfalls entpackt?

Im Ursprungsarchiv befinden sich eine unbekannt Anzahl von Dateien (ebenfalls Archive). In diesen befinden sich die für den Nutzer relavanten Daten, die er entpacken kann.

08.02.2012 - 18:21 Uhr

Hallo zusammen,

ich habe eine Frage zum Umgang mit großen Dateien in einer Anwendung.
Die Anwendung soll eine Archiv-Datei öffnen und alle vorhandenen Dateien in einer ListBox auflisten. Die enthaltenden Dateien sind wiederum nur Archive, deren Dateien ebenfalls Aufgelistet werden sollen (gegebenenfalls auch entpackt).

Da die ursprünglichen Archive sehr groß sein können (bis 900MB), bin ich mir unsicher wie ich diese Handhaben soll. Sollte die Archiv-Datei über die gesamte Laufzeit geöffnet bleiben?
Wäre es effektiver erst einmal alle Dateien aus dem Ursprünglichen Archiv aufzulisten (inkl.Offset + Länge) und nur bei Bedarf die Datei zu öffnen?

Ich wäre für Hinweise dankbar.

27.05.2010 - 15:02 Uhr

Danke, ich werde wohl zur StringCollection greifen.

26.05.2010 - 14:45 Uhr

Hallo zusammen,

ich habe ein Problem bei der Xml Serialization einer Klasse.
Meine Klasse sieht folgendermaßen aus:


[XmlRoot("Number1")]
    public class Testclass
    {
    
      private string _text1;
      private List<string> _list1 = new List<string>();
      private List<KeyValuePair<string, string>> _list2 = new List<KeyValuePair<string, string>>();
      
        [XmlElement("name")]
        public string Text1
        {
            get { return _text1; }
            set { _text1 = value; }
        }
        
        [XmlArray("Listen")]
        [XmlArrayItem("type")]
        public List<string> List1
        {
            get { return _list1; }
            set { _list1 = value; }
        }
        
        [XmlArray("KeyValues")]
        [XmlArrayItem("value")]
        public List<KeyValuePair<string, string>> List2
        {
            get { return _list2; }
            set { _list2 = value; }
        }
      }

Die Serialisierung funktioniert soweit, bis auf list2 mit KeyValuePair, bei der in der generierten Xml immer "<KeyValuePairOfStringString/>" drin steht.
Wieso kann ich eine List serialisieren aber kein KeyValuePair bzw. wie kann ich ein KeyValuePair serialisieren?

25.05.2010 - 10:59 Uhr

Hallo zusammen,

ich möchte an ein DataGridView ein KeyValuePair binden, und die beiden entstehenden
Columns an 2 TextBoxen.


first_DGV.DataBindings.Add("Text",class1, "keyValuePairTest");
textBox.DataBindings.Add("Text", first_DGV, "key" ,true, DataSourceUpdateMode.Never);

Ich erhalte die Meldung das er an den PropertyName nicht binden kann.
Wer kann mir dabei helfen bzw was das richtige Property?
Außerdem würde gern bei DataBindings bleiben, da ich so manuell über


textBox.DataBindings["Text"].WriteValue();

selber bestimmen kann, wann die Daten zurük geschrieben werden.

20.05.2010 - 18:03 Uhr

Wenn ich dann einen Knoten auswählen würde, wäre aber kein Text in der Texbox sichtbar, da ja der das DataBinding noch nicht gesetzt wäre.

20.05.2010 - 17:56 Uhr

Tut mir leid aber das versteh ich nicht. Die TextBox DataBinding wird doch in Abhängigkeit des gewählten Knoten aus dem TreeView gesetzt.

20.05.2010 - 17:28 Uhr

Hallo zusammen,

ich habe einen treeView,eine TextBox und einen Button. Wenn man in dem TreeView ein Knoten auswählt wird der TextBox DataBinding geändert und anhand des Knotennamen der Text aus der test Klasse in der TextBox angezeigt.


private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
                textBox.DataBindings.Clear();
                textBox.DataBindings.Add("Text", _testClass, treeView1.SelectedNode.Name);
                textBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnValidation;
         }

class testClass 
    {
        private string _a = "String A";
        public string A
        {
            get { return _a; }
            set  { _a = value;}          
        }

        private string _b = "String B";
        public string B
        {
            get { return _b; }
            set { _b = value; }
        }
}

Die Änderung soll aber erst validiert/gespeichert werden wenn man auf den Button klickt,
also habe ich gedacht ich setze den DataSourceUpdateMode auf OnValidation.
Nun wird natürlich eine Aktualisierung auch durchgeführt wenn die TextBox den Focus verliert. Wie kann ich das Validieren/Speichern des Textes erst durchführen wenn man den Button gedrückt hat?

04.05.2010 - 14:11 Uhr

Aber solang der Thread noch läuft sind ja auch alle erzeugten Objekte noch am Leben oder irre ich mich?

Es mag für mein kleines Programm sicherlich keinen Einfluss haben, aber bei größeren Programmen sollte man doch auf sowas achten?

04.05.2010 - 11:39 Uhr

Wenn die timeConsuming() fertig ist, wird das event geworfen. das ist nichts anderes als in die methode Event_FromThread aufzurufen. hier ist man noch im backgroundthread. dann wird in der methode geprüft, ob der aktuelle thread der hauptthread ist. wenn nicht, ruft man invoke auf. Das heißt das der Hauptthread die methode ausführen soll(this.Invoke(new MethodInvoker(Event_FromThread));) dabei wartet der hintergrundthread. wenn der hauptthread die methode ausgeführt hat, wird wieder zum hintergrundprozess gewechselt, und dieser am ende der Work() methode beendet

schöne Erklärung, danke.

Mir ist bewusst das mein thread solang läuft bis der Code in Event_FromThread abgearbeitet wurde und sich erst dann beendet.

Ich warte ja in der Form1 auf Daten die mit der Thread erzeugt. Sobald der Thread fertig ist soll er bescheid sagen damit ich mit den erzeugten Daten in der Form1 weiter abeiten kann. Wenn ich die Daten aber in der Event_FromThread verarbeite bleibt der Thread weiterhin am leben, was ich gern vermeiden würde.

Ich hatte an so etwas gedacht wie beim BackgroundWorker mit dem RunWorkerCompleted Event.

04.05.2010 - 00:03 Uhr

Entweder ich habe etwas missverstanden oder ich mache etwas falsch.

Form1:


private void test()
{
  ....
  testPanel.Visible = true;
  test1 = new TestClass();
  test1.Event_FromThread += (test1.EigenesEvent)Event_FromThread;
  test1.startMethode()
}

void Event_FromThread()
{
    if (this.InvokeRequired)
    {
         this.Invoke(new MethodInvoker(Event_FromThread));
         return;
    }
       //Sagt das der Thread noch da ist.
       Console.WriteLine("IsAlive=" + test1.thread.IsAlive);
}

TestClass:


public class TestClass
{
    public delegate void EigenesEvent();
    public event EigenesEvent Event_FromThread = null;
    ...
}

public void startMethode()
{
     thread = new Thread(new ThreadStart(this.Work));
     thread.IsBackground = true;
     thread.Name = "My Worker.";
     thread.Start();
}

private void Work()
{
    timeConsuming();
    if (Event_FromThread != null)
        {
           Event_FromThread();
        }
}

Sobald ich also wieder in der Form1 gelandet bin und den MethodInvoker ausgeführt habe lasse ich mir in der Konsole den Status des test1.thread ausgeben und der sagt mir das er noch am leben ist. Ich könnte diesen natürlich mit thread.abort() beenden, bezweifel aber das dies so richtig ist.

03.05.2010 - 20:35 Uhr

Danke herbivore.

Nur damit ich das richtig verstehe:
Nachdem also die timeConsuming Methode abgearbeitet wurde und mein Event geworfen wurde kann ich mit Invoke normal in meiner Form die erzeugten Daten weiterverarbeiten und der erstellte Thread wird beendet?

03.05.2010 - 19:44 Uhr

Du kannst das Event werfen und in der Form1 fangen. Dann musst du allerdings in den Thread der Form1 wechseln:

Hatte es gerade mit dem Event versucht und schon hatte ich einen Thread übergreifenden Vorgang. 😃

Ich hätte noch eine Frage zum geposteten Code:

Sobal das Event geworfen wurde, wechsel ich in den Gui Thread.
Wird der timeConsuming Thread dennoch beendet?

03.05.2010 - 18:24 Uhr

Hallo zusammen,
ich habe eine Frage zum beenden von Threads.
Folgender Sachverhalt:

Ich starte aus meiner Form eine Methode in einer anderen Klasse die sehr zeitaufwendig ist. In meiner Form wird ein Panel mit einer ProgessBar dargestellt.
Damit meine Gui nicht blockiert wird, lasse ich die Methode in einem Thread laufen.

Form1:


private void test()
{
  ....
  testPanel.Visible = true;
  TestClass test1 = new TestClass();
  test1.startMethode()
}

TestClass:


public void startMethode()
{
            thread = new Thread(new ThreadStart(this.Work));
            thread.IsBackground = true;
            thread.Name = "My Worker.";
            thread.Start();
}

private void Work()
{
    timeConsuming();
}

  1. Wird der Thread automatisch beendet wenn die timeConsuming() Methode
    beendet wurde oder muss ich da selber eingreifen?
  2. Was kann ich tun um in der Form1 auf die Beendigung des Threads zu reagieren?
    Genügt es nach der timeConsuming() ein Event zu werfen?
20.04.2010 - 23:00 Uhr

Ja, ich bleibe im Read hängen die frage ist aber warum?

20.04.2010 - 19:42 Uhr

Hallo zusammen,
ich hätte mal eine Frage zum lesen von Daten über Telnet.
In viele Beispielen zum Thema wird das wie folgt realisiert:


byte[] recdata = new byte[tcpClient.ReceiveBufferSize];
            while (true)
            {
                int read = stream.Read(recdata, 0, recdata.Length);
                if (read == 0)
                    break;
            }

Mein Problem ist, das die break Bedingung nicht Eintritt und ich mich so in einer Endlosschleife befinde.
Meiner Meinung liegt es daran das stream.Read nicht 0 zurückliefert wenn keine Daten zum Empfang mehr vorhanden sind.
Wer kennt dafür ein Lösung?

14.04.2010 - 12:40 Uhr

Danke erstmal für die Hilfe, leider habe ich Probleme bei der Implementierung des Interfaces.

Zuerst wird das xml eingelesen:


public class PluginLoader
    {
        private string Name;

        public void loadXml(string path)
        {
            XmlDocument xdoc = new XmlDocument();
            xdoc.Load(path);
            Name = xdoc.SelectSingleNode("xpath").InnerText;

            PluginNr1 plug1 = new PluginNr1(); //Instanz des Plugin erzeugen
            plug1.Name = Name; //Xml wert dem Plugin übergeben
        }
    }

das Interface:


public interface IPlugin
    {
        string Name { get; }
    }

konkretes Plugin:


internal class PluginNr1 : IPlugin
    {
        private string _Name;

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
    }

Ist die Implementierung so richtig, denn über IPlugin bekomme ich keine Propertys angeboten oder hab ich grundlegend was falsch verstanden?

13.04.2010 - 20:42 Uhr

Hallo zusammen,
ich habe folgendes Problem:

Grundlegend soll die ganze Sache eine Art Plugin Implementierung sein.

Ich lade ein Xml Dokument und möchte die ausgelesenen Werte global Verwenden wobei nur eine Instanz des Plugin vorhanden sein soll.
Das Plugin besitzt keine Methoden sodern nur strings, list usw.

Meine momentane Implementierung ist folgende:

statische Plugin Klasse:


static class Plugin
    {
       private static string _NAME;

        public static string NAME
        {
            get { return Plugin._NAME; }
            set { Plugin._NAME = value; }
        }
     }

Xml Datei laden:


public class PluginLoader
    {
      private string Test;

        public void loadXml(string path)
        {
            XmlDocument xdoc = new XmlDocument();
            xdoc.Load(path);
            Test = xdoc.SelectSingleNode(xpath).InnerText;
            Plugin._NAME = Test;
        }
     }

Das ganze würde zwar funktionieren aber durch das set property kann der String auch im Programm geändert werden. Wie kann man es besser machen?

09.03.2010 - 18:33 Uhr

Danke vielmals,
ich hab es jetzt mal mit der Serialisierung versucht, bin mir aber nicht sicher ob das alles so richtig ist.
Übrigens müssen die Daten nur exportiert werden, die Verarbeitung wird in einem anderen Programm stattfinden.

Code der Form1 mit einer ComboBox und einem NumericUpDown ( Testweise )


public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void export_Click(object sender, EventArgs e)
        {
            xmlExport export = new xmlExport();
            einstellungen e1 = new einstellungen(this);
            werte w1 = new werte(this);

            export._einstellungen1 = e1;
            export._werte1 = w1;

            XmlSerializer serializer = new XmlSerializer(typeof(xmlExport));
            FileStream fs = new FileStream("test.xml", FileMode.Create);
            serializer.Serialize(fs, export);
            fs.Close();
            export = null;
        }

        public string _comboBoxItem
        {
            get { return comboBox1.SelectedItem.ToString(); }
        }

        public decimal _numericValue
        {
            get { return numericUpDown1.Value; }
        }
    }

und meine Xml Struktur


[XmlRoot("TestXml")]
    public class xmlExport
    {
        [XmlElement("Einstellungen")]
        public einstellungen _einstellungen1;
        [XmlElement("Werte")]
        public werte _werte1;

        public xmlExport() { }
    }

    public class einstellungen
    {
        [XmlElement("Element")]
        public string element;
        [XmlAttribute("ID", DataType = "int")]
        public int id;

        public einstellungen(Form1 _form1)
        {
            this.element = _form1._comboBoxItem;
            this.id = 1;
        }

        public einstellungen() { }
      }
    public class werte
    {
        [XmlElement("Wert")]
        public string wert;
        [XmlAttribute("value", DataType = "decimal")]
        public decimal value;

        public werte(Form1 _form1)
        {
            this.wert = "1";
            this.value = _form1._numericValue;
        }

        public werte() { }
    }

  1. Ist diese Vorgensweise so korrekt?
  2. Ich benötige ja Daten aus meiner Form1, gibt es noch andere Möglichkeiten um die Daten der Controls zu übergeben? Ich habe ehrlich gesagt keine Lust für alle benötigten Controls getter zu erstellen.
08.03.2010 - 18:47 Uhr

Hallo zusammen,

ich möchte gern Messwert die ich auslese in eine Xml Datei exportieren.
Da diese Messwert ohne die jeweiligen Messeinstellungen nichtssagend sind muss ich außerdem aus meinem Programm verschiedene Einstellungen von ComboBoxen, CheckBoxen usw. mit in die Xml schreiben. Ich wollte dabei alle, auch für die Messung irrelevante Werte aufnehmen. Die Elemente die nicht genutzt wurden wollte ich dann leer lassen.

Wie gehe ich dabei am besten vor?

Erzeuge ich mir dafür vielleicht ein Objekt und serialisiere es dann,

oder erzeuge ich das xml Dokument direkt in einer Klasse,


XmlDocument doc = new XmlDocument();
XmlNode myRoot, myNode;
XmlAttribute myAttribute;
 
myRoot = doc.CreateElement("AppendChild");
doc.AppendChild(myRoot);
 
myNode = doc.CreateElement("Child1");
myNode.InnerText = CheckBoxText;

16.02.2010 - 19:49 Uhr

Ich gehe davon aus das du diese Zeile meinst:


int position = (int)testTable.Rows[test_DGV.CurrentCell.RowIndex]["id"];

Ich muss die Position so abfragen, da die testTable eine Column id besitzt, jedoch mittels ColumnMapping = MappingType.Hidden im DataGridView nicht sichtbar ist.

16.02.2010 - 18:12 Uhr

Danke,
aber sobald der EventHandler aufgerufen wird steht wieder der Index der im DataGridView markierten Zeile drin.


test_DGV.CurrentCell = test_DGV.Rows[index].Cells[0];

EventHandler wird aufgerufen.


private void test_DGV_SelectionChanged(object sender, EventArgs e)
        {
          int position = (int)testTable.Rows[test_DGV.CurrentCell.RowIndex]["id"];
          setAnnonation(position);
         }

"position" enthält den zuletzt im DataGridView markierten Index.

16.02.2010 - 17:16 Uhr

Hallo zusammen,

wie der Titel schon sagt habe ich ein Problem mit der Funktion CurrentRow.

In einer Methode markiere ich eine Zeile meines DataGridView.


test_DGV.Rows[index].Selected = true ;

daraufhin wird das Event test_DGV_SelectionChanged(object sender, EventArgs e) ausgelöst.
In diesem rufe ich eine Methode auf, der ich den index der soeben selektierten Row mitgeben will.


private void test_DGV_SelectionChanged(object sender, EventArgs e)
        {
           int position = test_DGV.CurrentRow.Index;
           setAnnonation(position); 
        }

Das Problem ist, das CurrentRow immer den Index der zuletzt im DataGridView selektieren Row enthält und nicht die von mir gewünschte (markierte).

Für Hilfe wäre ich dankbar.

09.02.2010 - 16:45 Uhr

Hallo zusammen,

ich sitze bereits länger an folgendem Problem.
Von einem Gerät erhalte ich Werte in folgender Schreibweise:

"+1.10230000E-02"

mit dieser Methode:


Double.Parse(zahl, System.Globalization.NumberStyles.Any).ToString();

erhalte ich: 1102300

hiermit:


Double.Parse(zahl, System.Globalization.NumberStyles.AllowExponent).ToString();

erhalte ich eine FormatException ("Die Eingabezeichenfolge hat das falsche Format").

Wie kann ich diesen String korrekt umwandeln?

Danke

03.01.2010 - 14:59 Uhr

Es gibt also keine Möglichkeit einfach eine Zeile einzufügen,
ich muss bei einer Änderung immer ein neues Array anlegen?

03.01.2010 - 14:12 Uhr

Hallo zusammen,

Ich habe folgendes Problem:

Ich lese eine Datei ein und speichere sie in einem ByteArray.
Der Aufbau der Datei in Hexadezimal:

0500 4800 6100 6C00 6C00 6F00 0000 DF

Das erste Byte (05) gibt die Länge des folgenden Strings an (hier 5).
Dann folgen 5 Zeichen (Hallo).
Das letzte Byte (DF) ist das Abbruchkriterium.
Zwischen dem letzen Zeichen und dem Abbruchkriterium müssen 4 Byte liegen.

Wenn ich nun mittels meines Programm die größe des String ändere, bin ich darauf angewiesen in mein Byte Array Zeilen einzufügen bzw. zu löschen um die Konventionen einzuhalten. Welche Lösungen gibt es dafür bzw. sollte man komplett anders herangehen?

10.12.2009 - 12:48 Uhr

Ok, danke

Das artet dann aber in große Schreibarbeit aus wenn ich sehr viele Controls überwachen will.

10.12.2009 - 12:23 Uhr

Hallo zusammen,

Ich habe in einer GroupBox mehrere ComboBoxen und möchte diese auf ihre Auswahl hin überwachen.

Also nur wenn in jeder ComboBox etwas ausgewählt wurde soll ein anderer Button in der Form enabled sein.

Momentan mach ich das so:



public SettingsFRM()
{
InitializeComponent();
//EventHandler registrieren
comboBox1.SelectedIndexChanged += new EventHandler(ComboTest);
comboBox2.SelectedIndexChanged += new EventHandler(ComboTest);
}

//Eventmethode
private void ComboTest(object sender, EventArgs e)
{
    if (comboBox1.SelectedIndex >= 0 && comboBox2.SelectedIndex >= 0)
     {
        testButton.Enabled=true;
     }
}

Ist das die richtige Vorgehensweise oder gibt es da elegantere Wege, gerade wenn eine größere Anzahl von Controls überwacht werden sollen?

19.11.2009 - 20:26 Uhr

Hallo zusammen,
ich habe eine Anwendung mit 2 Forms. Eine MainForm und eine SettingsForm für die Programmeinstellungen.
Die Anwendung benötigt verschiedene Einstellungen die der User in der SettingsForm getroffen hat. Momentan hole ich mir diese über angelegte Propertys.
Außerdem nutze ich den SettingsProvider um meine Anwendungseinstellungen zu speichern.

Nun zur Frage:
Da die Einstellungen in der SettingsForm beim schließen sowieso mithilfe des SettingsProviders gespeichert werden, kann ich diese doch auch gleich in meiner MainForm mithilfe des SettingProviders wieder auslesen und so den Weg über die Propertys sparen oder gibt es dagegen Einwände?

01.11.2009 - 20:25 Uhr

Sehr schön, das ist mal eine andere Lösung. Danke!
Den PropertyNotifier würde ich mir gern mal anschauen.

Gibt es eigentlich eine Möglichkeit einen Beitrag im Forum als gelöst zu markieren?

27.10.2009 - 16:57 Uhr

Danke für die Hinweise.

Kann mir jemand erklären warum die Buttons nicht checked sind wenn ich darauf klicke?


 ToolStripButton[] TS_ARY = new ToolStripButton[3];
 TS_ARY.SetValue(multimeter_Nav_BT0, 0);
 TS_ARY.SetValue(sensor_NAV_BT1, 1);
 TS_ARY.SetValue(start_NAV_BT2, 2);

private void nav_TS_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
             foreach (ToolStripButton BTN in TS_ARY)
                {
                    if (!(BTN == e.ClickedItem))
                    {
                        BTN.Checked = false;
                    }
                    else
                    {
                        BTN.Checked = true;
                    }
                 }
         }

27.10.2009 - 15:40 Uhr

Es geht mir mehr um die allgemeine Vorgehensweise.
Ich hatte schon öfter das Problem das mehrer TextBoxen voneinander abhängig sind und diese entsprechend enabled/disabled werden mussten.

Nun steh ich wieder vor diesem Problem bei einem ToolStrip ( müssen Buttons sein )
und habe mich gefragt wie man so etwas am besten umsetzt.

Bei wenigen Steuerelementen kann man ja noch case/switch verwenden aber bei mehr als 10 wird die ganze Sache chon recht aufwendig.

27.10.2009 - 15:16 Uhr

Hallo zusammen,
ich habe mal eine allgemeine Frage zur Abhängigkeit von Steuerelementen.

Folgendes Beispiel:
Ich habe 3 Buttons auf einem ToolStrip.
Wenn ich nun ein Button anklicke soll dieser checked=true sein und die anderen checked=false.
Wenn ich einen anderen anklicke soll es sich entsprechend verhalten.
Wie bewerkstelligt man das am sinnvollsten?

20.10.2009 - 17:10 Uhr

Hallo zusammen.

Ich habe ein DataSet mit mehrern Tabellen.
Dieses DataSet wollte ich in ein Excel Format umwandel.
Da ich Office auf dem Anwenderrechner nicht vorraussetzen möchte, wollte ich SpreadsheetML verwenden. ( Gibt es noch andere Möglichkeiten? )
Ich habe mir dazu das Snippet Excel-Export ohne Excel von Rainbird angeschaut. Als Hinweis steht im Artikel

Außerdem lässt sich sehr leicht herausfinden, wie Excel was in XML darstellt, indem man eine Excel-Mappe mit dem gewünschten Inhalt von Hand erstellt und im XML-Format speichert.

Also habe ich eine neue Mappe ( Office2007 ) erzeugt, eine kleine Tabelle eingefügt und mit "Speichern unter" das Xml Format eingestellt. Dies wird jedoch mit dem Hinweis quittiert:
"Die XML-Daten können nicht gespeicher werden, weil die Arbeitsmappe keine XML-Zuordnung enthält."
Wo liegt das Problem?
Ich möchte ja eigentlich nur per C#-Code eine Tabelle erzeugen die alle Daten meines DataSet enthält und dazu wollte ich mir anschauen wie Excel die Tabelle erzeugt.