PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C# Ping von mehreren Hosts ermöglichen, aber wie?


JasonX
2012-04-05, 12:43:37
Hallo,

ich möchte gerade ein kleines Programm basteln, das permanent den Status
von Rechnern abfragen soll, und mir dann ausgibt ob sie online sind oder offline


Ich habe die Hosts in einer ListBox eingetragen.

Das ist die Quelle aus der sich die Ping-Funktion die Hostnamen holen soll, da ich über Namen pingen möchte.

Die Namen der ListBox werden schon ausgelesen, in einer Tick funktion lasse ich die Ausgaben der Namen alle (bis jetzt) 3 Sekunden aktualisieren.

Funktioniert bis jetzt richtig gut.

Mir kommt gerade nur nicht, wie ich es schreiben soll,
das er diese Namen auch zum Pingen verwenden soll.

Ich würde ja gerne jeden einzelnen eintrag mit in einen String setzen,
Jedoch weiß ich nicht wie ich das realisieren soll, das er für jeden eintrag einen eigenen String setzt.

Hier mal ein Bild und der Code, damit man ungefähr sieht was ich meine.

http://img534.imageshack.us/img534/9659/anhang.png (http://imageshack.us/photo/my-images/534/anhang.png/)

Uploaded with ImageShack.us (http://imageshack.us)




private void Pingloop_Tick(object sender, EventArgs e)
{
int firewallmarkiert;

lblHost.Text = "";
for (firewallmarkiert = 0; firewallmarkiert < lstHosts.Items.Count; firewallmarkiert++)
lblHost.Text +=
lstHosts.Items[firewallmarkiert] + "\n";


}

private void Ping2_Tick(object sender, EventArgs e)
{
Ping statusabrage = new Ping();

}

noid
2012-04-05, 13:03:24
... auch wenn ich deine Frage nicht verstehe:

http://msdn.microsoft.com/en-us/library/7hzczzed.aspx

?

JasonX
2012-04-05, 13:09:13
Wie man einen Ping macht ist mir schon klar,

ich meine jedoch,

Das statt dem Hostnamen ich ihm den Hostnamen als String geben möchte

String Hostname;
Ping pingBlub = new Ping ();
PingReply reply = pingBlub.Send (Hostname);

Jedoch habe ich die Hostnamen in einer Listbox, bei einer Textbox wärs mir ja klar

da mache ich: String Hostname = textbox.Text; (so grob in etwa :))

Wie gehe ich die Listbox von Oben nach unten ab und weise dem String "Hostname" einen neuen Wert zu?

noid
2012-04-05, 13:11:03
Auf die Listboxelemente mti einem Iterator zugreifen?

JasonX
2012-04-05, 14:10:27
Also,

der Ping wird jetzt abgesendet,

jedoch wird er immer nur an den ersten Eintrag der Listbox gesendet.

Hier mal ein Bild:

http://img39.imageshack.us/img39/9784/anhang2.png (http://imageshack.us/photo/my-images/39/anhang2.png/)

Uploaded with ImageShack.us (http://imageshack.us)

Hier der Code:

private void Pingloop_Tick(object sender, EventArgs e)
{
int firewallmarkiert;

lblHost.Text = "";
for (firewallmarkiert = 0; firewallmarkiert < lstHosts.Items.Count; firewallmarkiert++)
lblHost.Text +=
lstHosts.Items[firewallmarkiert] + "\n";


}

private void Ping2_Tick(object sender, EventArgs e)
{
//object s;
String host;
int x = 0;
Ping Superping = new Ping();

try
{
for (x = 0; x < lstHosts.Items.Count; x++)
{
host = Convert.ToString(lstHosts.Items[x]);
PingReply reply = Superping.Send(host);
if (reply.Status == IPStatus.Success)
{
lblResult.Text = "Online" + "\n";
}
else lblResult.Text = "Offline" + "\n";
}
}
catch (Exception ex)
{
lblResult.Text = "Fehler: " + ex.Message;
}
}


}
}

pollux
2012-04-05, 14:18:19
Ich bin kein Programmierer, kann kein C#, aber:

ich denke, du sendest zwar alle pings, schreibst aber das "online" immer an die gleiche Stelle

JasonX
2012-04-05, 14:20:03
Ich bin kein Programmierer, kann kein C#, aber:

ich denke, du sendest zwar alle pings, schreibst aber das "online" immer an die gleiche Stelle

Dafür ist ja hinter Online das + "/n". Das schickt einen Zeilenumbruch mit.

pollux
2012-04-05, 14:23:10
Dafür ist ja hinter Online das + "/n". Das schickt einen Zeilenumbruch mit.

yep, aber müsstest du nicht schreiben:

lblResult.Text = lblResult.Text + "Online" + "\n";

JasonX
2012-04-05, 14:27:45
Habs versucht. Schaut genauso aus.

pollux
2012-04-05, 14:30:18
aber für die offline-Zeile hast du's auch geändert?

JasonX
2012-04-05, 14:48:21
Ja,

kein Unterschied

JasonX
2012-04-05, 15:38:56
Keiner mehr eine Idee?

swr1973
2012-04-05, 16:40:04
Also eigentlich sollte das durch folgende Änderung funktionieren:


lblResult.Text = "";
for (x = 0; x < lstHosts.Items.Count; x++)
{
host = Convert.ToString(lstHosts.Items[x]);
PingReply reply = Superping.Send(host);
if (reply.Status == IPStatus.Success)
{
lblResult.Text += "Online";
lblResult.Text += "\n";
}
else
{
lblResult.Text += "Offline";
lblResult.Text += "\n";
}
}


vorausgesetzt, das lbResult.Text auch ein Multiline Text-Control ist. Ansonsten würdest du nur die erste Zeile angezeigt bekommen.
Bin allerdings nur C++ Entwickler und kann kein C#.

Gruß
swr

Gast
2012-04-05, 16:53:33
Bis du dir sicher, dass den label mehrere Zeilen anzeigen kann?
Lösch doch einfach mal "/n".

Dein Code sollte eigentlich immer 3 mal "online / offline" alle 3 Sekunden hinzufügen. Das löschen bei jedem Tick wäre auch noch wichtig.

Auch wenn deine Lösung ziemlich abenteuerlich ist, könnte sie funktionieren.

JasonX
2012-04-05, 17:21:40
Inwiefern abenteuerlich ?

Das will ich hören, wo mein Ansatz falsch ist, nicht das ich das Programm zu schwerfällig mache.


Btw.: Es klappt. Zumindest solange der Host online ist.

Bei jedem weiteren der offline ist, wirds träger und irgendwann haut sich die Fehlerbehebung rein.

Ich werde mal das (halb)fertige Programm online stellen, mit allem pipapo,
eventuell kann dann mal einer nachvollziehen woran es hapert das es bei offline hosts nicht klappt.

Hab sogar einen timeout von 800ms definiert.

JasonX
2012-04-05, 17:28:08
Wo kann ich es eigentlich hochlade? Kenne keinen Freehoster, wo ich mich nicht anmelden muss nur um mal schnell 45 kb hoch zu laden.

Zergra
2012-04-05, 18:07:30
In eine Zip und dann als Anhang :)

TheRaven666
2012-04-05, 18:08:49
file-upload.net

Mars007
2012-04-06, 13:48:27
Inwiefern abenteuerlich ?

Bei jedem weiteren der offline ist, wirds träger und irgendwann haut sich die Fehlerbehebung rein.

Hab sogar einen timeout von 800ms definiert.


Ich habe etwas ähnliches Programmiert. Damit die (offline-)Trägheiten sich nicht aufaddieren habe ich einfach jeden Ping in einem eigenen Thread gestartet.

CoconutKing
2012-04-09, 18:26:47
nutzt doch einfach die mittel von c# + wpf.

setzt ein datagrid für die untere statusanzeige ein, setzt die datasource davon auf ne oberservablecolltection, mode=oneway. dann muss dein ping-thread nur den status eines clients in der collection ändern und die anzeige im grid wird autom. upgedated.

solche text-anzeige wie du sie machst sind (später) aufwendiger, unschöner und für grössere mengen an ausgabetext nicht geeignet.

PatkIllA
2012-04-09, 20:41:55
Dann sollten die Pingobjekte aber auch noch INotifyPropertyChanged unterstützen. Dann klappt das Databindung auch ordentlich.
Aus irgendeinem Grund fangen die allermeisten mit Windows Forms an.

JasonX
2012-04-10, 08:02:17
Nö, ich habe bereits mit der Konsole angefangen, aber mein Techniker möchte das ich das als Windows Fenster mache, und da ich mit dem Galileo Buch erst mal in Windows Forms eingelernt wurde möchte ich das erst mal mit so kleinen Sachen festigen. Später schwenk ich noch auf WPF um, jedoch noch nicht.

Sorry das ich jetzt erst Poste. Ostern und so ^^...

Hier die kleine File.

http://www.file-upload.net/download-4258778/Firewall-Verbindungschek.rar.html

Das ist das Progrämchen mit Sourcecode usw, ka was man alles zum Nachvollziehen braucht.

MfG
Jason

Ps: Bevor die ersten schreien, das soll noch nichts professionelles sein, ich habe nur eine Aufgabe bekommen, weil ich rumgeheult habe das ich nichts für die Firma kenne, das sie brauchen könnte, und wo ich mich mehr einlerne in C#.

Und Danke schonmal im vorraus.

PatkIllA
2012-04-10, 09:03:52
Die Sache ist nur, dass man mit WPF komplett von vorne anfängt und gar nicht erst versuchen sollte das wie in Forms zu machen.
War jetzt auch nur eine allgemeine Anmerkung.

CoconutKing
2012-04-10, 18:54:34
wpf "macht" auch windows-fenster, was sonst?

wenn man deinen satz so liest, könnte man denken du meinst, mit wpf gibts keine "normalen" windows fenster :rolleyes:

PatkIllA
2012-04-10, 18:58:48
wpf "macht" auch windows-fenster, was sonst?

wenn man deinen satz so liest, könnte man denken du meinst, mit wpf gibts keine "normalen" windows fenster :rolleyes:
Es macht technisch andere Fenster, die man auch anders benutzt. Eigentlich ist außer der Tatsache, dass da ein Fenster ist alles anders.
Man kann in WPF zwar auch alles ähnlich wie in Forms machen, aber dann gewinnt man nichts bzw verliert sogar.
Wenn man dann umsteigt ist das Forms-Wissen eher hinderlich, aber wenn man dann irgendwann mal die ganze Eleganz von DataBinding und Templates erfasst hat will man nicht mehr zurück.

JasonX
2012-04-11, 16:16:31
Ich habe ein anderes Problem das ich nicht weiß wie ich es lösen soll.

Ich möchte vor einem Eintrag in die Listbox, die Listbox durchsuchen ob der Wert bereits vorhanden ist.

Wenn ich in die Textbox "hanspeter" eingetragen wird, und ich auf den Button hinzufügen klicke, soll die ganze Listbox durchsucht werden, ob der Wert schon exestiert.

Habs schon mit for schleifen und foreach versucht, komme aber nicht weiter.
Entweder er trägt den Wert trozdem ein, oder er macht gar nichts.

private void cmdAdd_Click(object sender, EventArgs e)
{
string rechhost = txtHost.Text;
string kundehost = txtKunde.Text;

if (rechhost != "" && kundehost != "")
{
int i1 = 0;
for ( i1= 0; i1 < lstKunde.Items.Count; i1++)
{
if (Convert.ToString(lstKunde.Items[i1]) != kundehost)
{

}
else
{


MessageBox.Show("Existiert bereits!");
break;

}

}

lstHosts.Items.Add(rechhost);
lstKunde.Items.Add(kundehost);


}


else MessageBox.Show("Bitte geben sie einen Kundennamen und Firewall-Adresse ein!");
}

AwesomeSauce
2012-04-11, 16:43:56
Vielleicht geht sowas: http://msdn.microsoft.com/en-us/library/e5et1818.aspx


int index = listBox1.FindString(searchString);
// Determine if a valid index is returned. Select the item if it is valid.
if (index != -1)
listBox1.SetSelected(index,true);
else
MessageBox.Show("The search string did not match any items in the ListBox");

Monger
2012-04-11, 18:04:53
Sind denn überhaupt die Items in der ListBox vom Typ String?

In WPF ist die Trennung sehr scharf: Eine ListBox enthält Objekte vom Typ ListBoxItem. Deren Darstellung ist üblicherweise an irgendein Objekt gebunden (im einfachsten Fall einen String), aber wenn du den Inhalt der ListBox auslesen oder manipulieren willst, sollst du normalerweise direkt an die Quelle gehen, statt irgendwie über die Oberfläche dich da runterzuhangeln.

Das ist, wenn mans richtig macht n bissl knifflig. Datenbindung ist kein 08/15 Thema. Aber schau erstmal was konkret bei deinem "Convert.ToString" rauskommt. Ich vermute, nicht was du erwartest.

JasonX
2012-04-12, 08:12:14
Nein, es kommen keine Strings raus, die Werte sind vom Typ Object,
jedoch kann ich die Werte in Strings konvertieren, was, wie du bereits geschrieben hast mit dem Convert.ToString passiert.

Es sollte auch funktionieren, da ich, wie im Codeschnipsel auf der ersten Seite, diese Vorgehensweise schon für meine Ping-Abfrage genutzt habe, und die geht inzwischen einwandfrei.

Inzwischen habe ich es herausgefunden woran es lag.

private void cmdAdd_Click(object sender, EventArgs e)
{
string rechhost = txtHost.Text;
string kundehost = txtKunde.Text;
if (rechhost != "" && kundehost != "")
{
int i1 = 0;
for ( i1= 0; i1 < lstKunde.Items.Count; i1++)
{
if (Convert.ToString(lstKunde.Items[i1]) != kundehost)
{
}
else
{


MessageBox.Show("Existiert bereits!");
goto ende;

}

}
lstHosts.Items.Add(rechhost);
lstKunde.Items.Add(kundehost);


}


else MessageBox.Show("Bitte geben sie einen Kundennamen und Firewall-Adresse ein!");
ende: { }
}


Das funktionert.
Er trägts ein wenn`s nicht vorhanden ist, und Spuckt die Messagebox aus wenn`s vorhanden ist.

JasonX
2012-04-12, 11:33:01
Neue Frage:

Hat sich erledigt sorry...

Monger
2012-04-12, 11:45:40
Nein, es kommen keine Strings raus, die Werte sind vom Typ Object

Jedes Objekt ist vom Typ Object, du musst dir schon im Debugger anschauen was du wirklich in der Hand hast. Aber es funktioniert ja, daher okay.


MessageBox.Show("Existiert bereits!");
goto ende;


Goto in C#? Bist du des Wahnsinns?? :D

In VB.NET kann ich mir wenigstens noch erklären woher das kommt (die alten VB6 Veteranen wissens halt nicht besser), kriminell ist es aber da wie dort.

Benutz gefälligst "return" um ne Funktion vorzeitig zu verlassen.

Gast
2012-04-12, 19:25:03
dein code ist echt schrecklich, sry.

angefangen von der benennung der variablen bis hin zum stil

JasonX
2012-04-16, 08:14:58
Jedes Objekt ist vom Typ Object, du musst dir schon im Debugger anschauen was du wirklich in der Hand hast. Aber es funktioniert ja, daher okay.


Goto in C#? Bist du des Wahnsinns?? :D

In VB.NET kann ich mir wenigstens noch erklären woher das kommt (die alten VB6 Veteranen wissens halt nicht besser), kriminell ist es aber da wie dort.

Benutz gefälligst "return" um ne Funktion vorzeitig zu verlassen.


Bitte, bitte nicht hauen, :frown:

ich hatte keine andere Möglichkeit gefunden die Schleife so zu verlassen, so das er das macht was er soll.
Bin gerne dazu bereit etwas zu ändern wenn du mir sagst wie ich es besser machen kann, return hat bei mir nicht geklappt, aber vllt war der Return auch an der falschen
Position im Code.

/edit: Habs geändert, aus goto wurde nun return.

dein code ist echt schrecklich, sry.

angefangen von der benennung der variablen bis hin zum stil

Sorry, aber wenn du von Anfang an gelesen hättest, ist das zum einlernen,
ich habe selbst bemerkt, das er nicht der Hit ist, ich bin gerade dabei zu schauen, das ich das alles umschreibe, weil ich selbst
schon Punkte gefunden habe, wo der Aufbau auf seine Grenzen stößt.

Btw.: Was meinst du mit Stil?

Monger
2012-04-16, 13:42:14
Bitte, bitte nicht hauen, :frown:

ich hatte keine andere Möglichkeit gefunden die Schleife so zu verlassen, so das er das macht was er soll.
Das war jetzt auch nicht ganz ernst gemeint! ;-)

Es gibt halt gewisse Elemente einer Programmiersprache die "veraltet" sind, die man zwar theoretisch noch schreiben kann, die aber aus heutiger Sicht aus verschiedenen Gründen gemieden werden sollten.

Grundsätzlich mal gibt es ein paar Regeln die heute als "guter Code" betrachtet werden, dazu gehört z.B. dass die "Sichtbarkeit" von Code so klein wie möglich sein sollte, damit man bei eventuellen Änderungen nicht überall in der Datei suchen muss, sondern nur in dem davon betroffenen Abschnitt.
"Goto" durchbricht ein bißchen dieses Konzept, weil die Zielsprungmarke sonstwo in der selben Methode sitzen kann.
In die selbe Kathegorie gehört, dass man Variablen möglichst lokal und erst dann deklarieren sollte wenn man sie braucht.

Was das Return betrifft: das läuft unter dem Stichwort "Fail fast", d.h. wenn die Methode schon abbricht, dann soll sie das möglichst weit oben tun. "Return" sorgt dafür dass genau an dieser Stelle Schluss ist. Mit einem Goto oder If erst große Codebereiche zu überspringen, nur um dann anschließend doch nichts wichtiges zu tun ist halt verwirrend, weil du ständig hoch und runter scrollen musst um zu verstehen was dein Code wirklich tut.

Um mal dein Codebeispiel aufzugreifen: man könnte das stattdessen auch so schreiben:


private void cmdAdd_Click(object sender, EventArgs e)
{
string rechhost = txtHost.Text;
string kundehost = txtKunde.Text;
if (rechhost == "" || kundehost == "")
{
MessageBox.Show("Bitte geben sie einen Kundennamen und Firewall-Adresse ein!");
return;
}

foreach(Object kunde in lstKunde)
{
if (Convert.ToString(kunde) == kundehost)
{
MessageBox.Show("Existiert bereits!");
return;
}
}

lstHosts.Items.Add(rechhost);
lstKunde.Items.Add(kundehost);

}

JasonX
2012-04-16, 17:12:52
Ok,
wie gesagt, genau da habe ich jetzt das return eingesetzt.
Klappt auch genauso wie es soll.
Bin ja nicht lernresistent. :-)

Hat jemand eine Idee, wie ich den Status "Online/Offline" besser ausgeben kann, damit ich zum beispiel jedes Online grün einfärbe und jedes Offline rot.

Ich merke, das ich da mit label nicht wirklich weiter komme. Hatte sogar versucht wärend der Runtime jedes label dynamisch erstellen zu lassen, aber das funktioniert nicht so ganz wie ich es mir vorgestellt habe, sprich, es erstellt sich kein label.

Ich würde dafür sogar den Code nochmal umschreiben, wenn der Zugriff auf die Daten der ListBox nicht mehr gewährleistet wär.
Nur bitte keine Datenbanksachen, in SQL läuft bei mir da zur zeit echt noch nichts.

Aber eventuell gibt es da eine bessere Ausgabemöglichkeit.

Bis jetzt sieht mein Ping so aus.

private void Ping_Tick(object sender, EventArgs e)
{
string host;
int x = 0;
Ping Superping = new Ping();
int timeout = 1000;

for (x = 0; x < lstHosts.Items.Count; x++)
{

try
{
host = Convert.ToString(lstHosts.Items[x]);
PingReply reply = Superping.Send(host, timeout);
if (reply.Status == IPStatus.Success)
{
lblResult.Text += lblResult.Text = "Online" + "\n";
status = "Online";
}
else if (reply.Status != IPStatus.Success)
{
//lblResult.Text += lblResult.Text = "-------" + "\n";
status = "Offline";
if (status == "Offline")
{
reply = Superping.Send(host, timeout);
if (reply.Status == IPStatus.Success)
{
lblResult.Text += lblResult.Text = "Online" + "\n";
status = "Online";
}
else if (reply.Status != IPStatus.Success)
{
lblResult.Text += lblResult.Text = "-------" + "\n";
status = "Offline";
}
}

}
if (status == "Offline" && tray.Visible == true)
{

// MessageBox.Show("Mindestens eine Firewall ist nicht mehr zu erreichen");
tray.BalloonTipTitle = "ACHTUNG !!! Wichtiger Hinweis! FIREWALL EINES KUNDEN OFFLINE !!!";
tray.BalloonTipIcon = ToolTipIcon.Error;
tray.BalloonTipText = "Mindestens eine Firewall ist nicht mehr erreichbar.";
tray.ShowBalloonTip(1000);

}
else if (status == "Online" && tray.Visible == true)
{

}
}
catch
{
if (tray.Visible == false)
lblResult.Text += " Hostname unbekannt" + "\n";
else
{
tray.BalloonTipTitle = "ACHTUNG !!! Wichtiger Hinweis! FIREWALL EINES KUNDEN OFFLINE ODER KANN NICHT AUFGELÖST WERDEN !!!";
tray.BalloonTipIcon = ToolTipIcon.Error;
tray.BalloonTipText = "Mindestens eine Firewall kann nicht aufgelöst werden";
tray.ShowBalloonTip(1000);
}
}
}

}


Wo und wie müste ich ansetzen damit ich Offline und Online jeweils zeilenweise einfärbe.
Bis jetzt färbt sich jedes label komplett ein und das ist ja falsch.
Deswegen versuche ich jetzt umzudenken, weiß aber nicht womit ich das realisieren könnte.

MfG und danke im vorraus.
Jason

robobimbo
2012-04-16, 22:16:23
Du solltest ein DataGridView verwenden. Damit kannst Du wunderbar den von Dir gewünschten Effekt erzielen.

Hier ein kurz zusammengewürfelter Prototyp:
http://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=42530&stc=1&d=1334607140

Und das der Code dazu:

using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Pinger.Properties;
using System.Threading.Tasks;
using System.Net.NetworkInformation;
using System.Threading;

namespace Pinger {

public partial class Form1 : Form {
// Liste mit den Daten
public ICollection<Host> Hosts { get; set; }

public Form1() {
InitializeComponent();

// Erzeugen von Demodaten
Hosts = new List<Host>();
Hosts.Add(new Host() { Customer = "Host 1", Hostname = "192.1.1.211", Status = Resources.network });
Hosts.Add(new Host() { Customer = "Host 2", Hostname = "127.0.0.1", Status = Resources.network });
Hosts.Add(new Host() { Customer = "Host 3", Hostname = "127.0.0.2", Status = Resources.network });
Hosts.Add(new Host() { Customer = "Host 4", Hostname = "127.0.0.3", Status = Resources.network });

// Zuweisen der Datenquelle (Object Data Source) an das DataGrid
this.dataGridView1.DataSource = Hosts;

// Mit dem CancellationToken kann man den Task dann später mal abbrechen (zb. für einen Stop-Button, oder beim Beenden des Programmes)
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

// Der Ui-Thread soll nicht blockiert werden von dem Pinger der im Hintergrund läuft
var UiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

// Das ist die eigentliche Ping-Funktion (in einer Endlosshcleiffe wird alle zwei Sekunden ein Ping auf einem
// Host aus der Liste durchgeführt, und je nach ergebnis der Status gesetzt)
Task pingTask = Task.Factory.StartNew((_) => {
while (true) {
foreach (var host in Hosts) {
System.Threading.Thread.Sleep(2000);
Ping p = new Ping();
PingReply r = p.Send(host.Hostname);
if (r.Status == IPStatus.Success) {
host.Status = Resources.network_add;
var t = Task.Factory.StartNew(() => this.RefreshDataGrid(), token, TaskCreationOptions.None, UiScheduler);
} else {
host.Status = Resources.network_remove;
var t = Task.Factory.StartNew(() => this.RefreshDataGrid(), token, TaskCreationOptions.None, UiScheduler);
}
}
}

}, token, TaskCreationOptions.None);
}

// Kleine Methode um das DataGrid bei Datenänderung neu aufzubauen (Wird von dem Hintergrundtask aufgerufen)
public void RefreshDataGrid() {
this.dataGridView1.Refresh();
}
}

// Das Datenobjekt
public class Host {
public string Customer { get; set; }
public string Hostname { get; set; }
public Image Status { get; set; }
}
}


Nur schnell zusammengepfuscht. Mit dem DataGridView hast du noch weitere Möglichkeiten wie sortieren, hinzufügen, ändern usw.

Wenn du beim Beenden bzw. Starten noch den Inhalt der Liste in eine Textdatei schreibst bzw. liest, bleiben Dir die Daten auch erhalten. Solange Du damit keine 10000 Einträge verwaltest, sollte die Geschwindigkeit auch kein Problem sein.

JasonX
2012-04-17, 08:05:00
An genau sowas habe ich auch schon gedacht, muss nur suchen, wo das ist, da das einzige DataGrid das ich bis jetzt fand eine Quelle wollte.

Dankeschön.

Monger
2012-04-17, 09:20:02
In WPF funktioniert das alles etwas anders. Im Endeffekt eleganter, aber man muss das Pferd halt andersrum aufzäumen.

Das ist aber ein sehr eigenes Kapitel, ich weiß nicht wieviel Sinn es macht jetzt darauf detailliert einzugehen. Vom Prinzip her: du musst erstmal deine Ergebnisse (Hostnamen, Status) in eine Liste von irgendeiner Form von Objekt stecken. Also z.B. "List<Host>", wobei Host sinngemäß so aussieht:


Class Host
{
Property String HostName {get; set;}

Property String Status {get; set;}

}

Diese Liste kannst du dann dem DataGrid als Source geben, und die einzelnen Spalten dann an den Inhalt der Properties binden.
Und damit die Zeile entsprechend grün oder rot gefärbt wird, muss die Zeilenfarbe per ValueConverter an das Status Property gebunden werden.

Du kannst theoretisch auch in WPF prozedural dem Grid einzelne Einträge hinzufügen, aber das ist mühsam und fehlerbehaftet. Ist im Endeffekt wesentlich einfacher den vorgesehenen Weg zu gehen und an eine entsprechende Source zu binden.

JasonX
2012-04-17, 10:37:12
Habe gerade Testweise, in einem Testprojekt (das war doppeltgemoppelt XD)

das mit dem Datagrid versucht.

Eintragen per Button geht.

Jetzt versuche ich den Inhalt einer Textbox mit einer der Cellen zu vergleichen.

Ich dachte eigentlich das er Zeilenweise die DataGrid abgeht um zu prüfen ob der Wert schon vorhanden ist.

Ich habe die Cols: Kunde, Host, Status

Die einzelnen Zellen des Cols Kunde sollen mit dem Textboxeintrag verglichen werden.

string kunde = txtKunde.Text;

foreach (DataGridView row in dGVFirew.Rows)
{
if (dGVFirew.CurrentRow.ToString() != kunde)
{
}
else
{
MessageBox.Show("Kunde existiert bereits!");
return;
}
}

Wo liegt der Fehler im rechten Bild??

Er fügt ohne Muh und Mäh ein und ein und ein. Ohne zu schreien das der Kunde vorhanden ist.

robobimbo
2012-04-17, 13:43:59
Wenn Du Dein datagrid mit einer ObjectDataSour befüllst, dann brauchst Du nicht kompliziert auf das Datagrid zugreifen, sondern Du kannst Direkt mit den Daten arbeiten - siehe meinen Code...