das "&"-Zeichen ist in Windows Forms ein Steuerzeichen für Tastaturkürzel (Mnemonics).
Die kannst Du für Dein Label (und alle anderen Controls) auch abschalten:
hier sagst Du, dass Deine Collection Dictionary<Guid, IComponent> enthält.
Dictionary<Guid, TComponent> GetComponentPool<TComponent>() where TComponent : IComponent
hier willst DU aber Dictionary<Guid, TComponent> zurückgeben. Daher der erste Konvertierungsfehler. Hier müsstest Du auch Dictionary<Guid, IComponent> zurückgeben.
genauso müsstest Du hier nicht Dictionary<Guid, TComponent> erstellen und hinzufügen sondern ebenfalls ein new Dictionary<Guid, IComponent>(). Daher der zweite Konvertierungsfehler.
Ob dann der Zweck so wie gedacht weiterhin erfüllt wird und/oder der Indexer von KeyedByTypeCollection richtig funktioniert, kann ich so nicht sagen.
GULP ist ziemlich bekannt.
Da ich selbst kein Freelancer bin, habe ich es noch nicht selbst genutzt, habe aber gelegentlich mal mit Leuten zusammengearbeitet, die von da kamen.
Socket.Bind will Deine lokale Adresse haben (oder Du könntest IPAddress.Any nehmen).
Die Adresse der Gegenstelle bekommst Du dann mit, wenn Du den Broadcast empfängst.
Beachte aber auch, dass Deine lokale IP (192.168.200.231/255.255.255.0) in einem anderen Subnetz liegt, als die IP, die Du in Deinem Code verwendest (also vermutlich die Server-IP).
Des weiteren würde ich Dir empfehlen, statt Socket den UdpClient zu verwenden.
also ehrlich gesagt versteh ich es auch nicht so ganz - könnte an der Beschreibung liegen
Ich vermute, dass hier die entscheidende Information noch fehlt.
@Ichthys
Zitat
Und das passiert bei mir bei einer frisch erstellten WPF-Anwendung
kannst Du dann mal eine minimale Beispiel-Solution zippen und hochladen, die den Fehler aufweist?
Dann kann man das vielleicht nachvollziehen.
Gruß, MarsStein
Edit: und verrat uns bitte, mit welcher VS-Version Du arbeitest...
wenn die Darstellung irgendwann so aussehen soll wie im Bildanhang, dann solltest Du Dir mal Graphics.RotateTransform ansehen. Damit werden dann auch die Zahlen entsprechend mitrotiert/gekippt.
Überhaupt ist diese Aufgabe damit viel einfacher lösbar, Du brauchst dann die ganzen Sinus/Cosinus Berchnungen nicht - du rotierst einfach die Zeichenebene immer weiter um einen bestimmten Winkel und kannst dadurch jede Zahl quasi immer an die selbe xy-Koordinate zeichnen.
der ResponseStream der HttpWebResponse gibt Dir - wie Du schon festgestellt hast - nur die Nutzdaten raus. Das Parsen der Chunks wird bereits intern gemacht.
Das ist normalerweise auch das, was man will - schließlich handelt es sich trotz der Chunks um eine zusammenhängende Response. Die ist eigentlich nicht dafür gedacht, in der Zusammensetzung der Chunks eine Semantik unterzubringen, sondern um bei aufwändiger Generierung einer Response bereits fertige Teile schon mal an den Client zu senden.
Das kannst Du Dir in den .NET-Quellen ansehen: GetResponseStream erstellt intern einen ConnectStream, der im Konstruktor bereits den ChunkParser erstellt. Du wirst an die Chunk-Metadaten mit HttpWebResponse also nicht so einfach drankommen.
Aber tja, so ist das eben, wenn man in die Cloud geht. Dann muss man zumindest mit so etwas rechnen.
empfinde ich darüber hinaus höchst unseriös. Stammtisch-Gerede.
Das ist leider typisch Deutsch und sehe ich auch immer nur in DE: Hauptsache den Leuten Angst machen statt sie sauber aufzuklären!
Eine absolut unseriöse Aussage, die schmerzlich und völlig falsch beinhaltet, dass die Cloud pauschal unsicherer ist. Absolut fahrlässig!
Da hast Du meinen Satz aber gründlich aus dem Kontext gerissen. Direkt im Satz vorher hatte ich auch geschrieben:
Zitat von MarsStein
Ich halte es generell schon für möglich, aber nicht für zwingend, dass dann ggf. eine Herausgabe von den Amerikanern erzwungen werden kann.
Eine Aussage, dass die Cloud pauschal unsicher sei, kann ich in diesem Kontext nicht erkennen, und war auch nicht beabsichtigt.
Ich habe auch überhaupt nix dagegen, wenn sich Firmen in der Cloud austoben und dort die (zugegeben hervorragenden) Rechenpower- und Skalierungsmöglichkeiten nutzen.
Ich habe nur etwas gegen den allgemeinen Trend, dass man als als Endnutzer mehr und mehr förmlich dazu gedrängt wird, persönliche Daten in der Cloud abzulegen oder durch Anbieter ablegen zu lassen.
Die Überladung, die einen String annimmt, kannst Du ein Suchmuster angeben.
Das gibt Dir wieder eine Auflistung von DirectoryInfo, die dem Suchmuster entsprechen.
Also einfacher geht's nun wirklich nicht. Die Suchmuster unterstützen auch Wildcards wie XYZ_*.
Hast Du Dir die verlinkten Dokuseiten überhaupt angeschaut?
Mach Dir zuerst mal eine DirectoryInfo mit dem Basispfad, in dem Du suchen willst.
Dann kannst Du mittels DirectoryInfo.GetDirectories kannst DU nach den gewünschten Ordnern suchen. Die Überladung, die einen String annimmt, kannst Du ein Suchmuster angeben.
Das gibt Dir wieder eine Auflistung von DirectoryInfo, die dem Suchmuster entsprechen.
Das gleiche nochmal für den "enthaltenen Ordner X".
Und da kannst du dann analog mit DirectoryInfoGetFiles nach der gewünschten Datei suchen.
Gruß, MarsStein
Edit: Oder eben rekursiv, wie Coffeebean vorgeschlagen hat.
Wenn Microsoft jetzt wider selber Zugang zu den Servern hat, können die US-Behörden sie dazu zwingen dort gespeicherte Daten herauszugeben.
Es geht nicht um den Zugang, sondern ob die Server von Microsoft betrieben werden.
Der CLOUD Act kann also nur greifen, wenn Microsoft (oder ein anderes amerikanisches Unternehmen) in Zukunft wieder selbst der Betreiber der Server ist.
Ob das juristisch einen Unterschied macht, ob Microsoft USA oder Microsoft Deutschland (oder eine anderen europäischen Niederlassung) die Server betreibt, kann ich nicht sagen - bin halt kein Jurist, und habe auch nicht wirklich Lust, mich in der Materie schlau zu machen.
Ich halte es generell schon für möglich, aber nicht für zwingend, dass dann ggf. eine Herausgabe von den Amerikanern erzwungen werden kann.
Aber tja, so ist das eben, wenn man in die Cloud geht. Dann muss man zumindest mit so etwas rechnen.
in dem Artikel wird ja nur aufgezeigt, dass der Server aus der Deutschland-Cloud mit einem von Microsoft (irgendwo) betriebenen Server kommuniziert.
Das finde ich nun im Zusammenhang mit Azure nicht wirklich verwuderlich, und von einer Übertragung personenbezogener Daten ist gar keine Rede. Wenn da Telemetriedaten fließen, dann halt auch nur mit der Server-IP (wären es die IPs der Clients, wäre das was anderes, davon war aber im Artikel keine Rede).
Insofern finde ich den Artikel jetzt auch nicht so doll - den Cloud-Hype aber übrigens auch nicht
das liegt daran, dass Du zuerst mit dem StreamReader auf den Stream losgehst, und anschließend versuchst, direkt einzelne Bytes aus dem Stream zu lesen.
Der StreamReader verwendet einen internen Lesepuffer, den er erst mal füllt. Dadurch liest er Dir dann schon einige Bytes unterm Hintern weg, und wenn Du die einzelnen Bytes lesen willst, ist der NetworkStream schon ein Stück weiter, als Du es erwartest.
Du kannst das mit dem StreamReader machen, dann musst Du aber alles damit lesen.
Dann brauchst Du aber auch noch einen StreamWriter, der dir das wieder sauber wegschreibt in einen MemoryStream. Achtung: Du brauchst dann ein 8-Bit Encoding im StreamReader und das gleiche nochmal im StreamWriter, mit einem Multibyte-Encoding wird das nix (und mit ASCII auch nicht), vor allem weil Du mit Accept-Encoding: gzip, deflate mit Sicherheit Binärdaten erhältst. Du kannst z.B. Encoding.Default verwenden (nicht zu verwechseln mit dem standardmäßigen Encoding des StreamReaders, das ist nämlich UTF8).
Also sowas würde funktioieren:
StreamReader reader = new StreamReader(stream, Encoding.Default);
//... deine ganze Header-Ausgabe
string hexChunkSize = reader.ReadLine();
int decChunkSizeInt = Convert.ToInt32(hexChunkSize, 16);
Console.WriteLine("ChunkSize (HEX): " + hexChunkSize);
Console.WriteLine("ChunkSize (DEC): " + decChunkSizeInt);
MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms, Encoding.Default);
while (decChunkSizeInt > 0)
{
var content = new char[decChunkSizeInt];
reader.ReadBlock(content, 0, decChunkSizeInt);
writer.Write(content);
// am Ende des Chunks das CRLF lesen
reader.ReadLine();
// und ab in die nächste Runde
hexChunkSize = reader.ReadLine();
decChunkSizeInt = Convert.ToInt32(hexChunkSize, 16);
Console.WriteLine("ChunkSize (HEX): " + hexChunkSize);
Console.WriteLine("ChunkSize (DEC): " + decChunkSizeInt);
}
writer.Flush();
// jezt stehen im MemoryStream genau die Nutzdaten, allerdings binär wegen gzip/deflate,
// die musst Du dann noch auspacken
Die bessere Lösung:
Besser ist es meiner Ansicht nach aber, die Daten gar nicht als Text zu verhackstücken, sondern direkt alles binär aus dem Stream zu lesen - weil es sich ja auch um Binärdaten handelt.
Dazu brauchst Du erst mal eine Hilfsmethode, die ein Zeilenende erkennt. Nach HTTP-Spezifikation kannst Du Dich dabei auf CRLF verlassen:
static byte[] ReadLine(NetworkStream stream)
{
MemoryStream ms = new MemoryStream();
int b;
while((b = stream.ReadByte()) != -1)
{
if (b == 13)
{
b = stream.ReadByte();
if (b == 10 || b == -1)
break;
}
ms.WriteByte((byte)b);
}
return ms.ToArray();
}
Diese kannst Du dann nutzen:
// die Ausgabe der Header erfolgt dann mit
Console.WriteLine(Encoding.ASCII.GetString(ReadLine(stream)));
//... und die anderen Zeilen dazu
// Chunksize in Dezimalzahl umwandeln und ausgeben
string hexChunkSize = Encoding.ASCII.GetString(ReadLine(stream));
int decChunkSizeInt = Convert.ToInt32(hexChunkSize, 16);
Console.WriteLine("ChunkSize (HEX): " + hexChunkSize);
Console.WriteLine("ChunkSize (DEC): " + decChunkSizeInt);
MemoryStream ms = new MemoryStream();
while(decChunkSizeInt > 0)
{
byte[] buffer = new byte[decChunkSizeInt];
stream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, buffer.Length);
// am Ende des Chunks das CRLF lesen
ReadLine(stream);
// und ab in die nächste Runde
hexChunkSize = Encoding.ASCII.GetString(ReadLine(stream));
decChunkSizeInt = Convert.ToInt32(hexChunkSize, 16);
Console.WriteLine("ChunkSize (HEX): " + hexChunkSize);
Console.WriteLine("ChunkSize (DEC): " + decChunkSizeInt);
}
// jezt stehen im MemoryStream genau die Nutzdaten, allerdings binär wegen gzip/deflate,
// die musst Du dann noch auspacken
dass die konkreten Typen, die für die Typargumente eingesetzt werden, zur Compilezeit feststehen
Die kannst Du eben nicht aus einer Funktion heraus erzeugen, da der Compiler den Code dieser Funktion ausführen müsste, damit der Typ zur Compilezeit bekannt wäre. Das kann und tut er aber nicht. Daher müssen die konkreten Typen bei Nutzung von Generics direkt im Code angegeben werden und nicht dynamisch (per Code) irgendwo hergezaubert werden.
@Glowhollow,
was Du da vorhast, geht so nicht.*
Das erstellen generischer Objekten und der Aufruf generischer Funktionen erfordern, dass die konkreten Typen, die für die Typargumente eingesetzt werden, zur Compilezeit feststehen (und nicht erst zur Laufzeit).
*Sowas kann man theoretisch dann über Reflection und den Emitter auch zur Laufzeit erzeugen - aber das hier durchzukauen wäre wohl etwas am Thema vorbei.
eine Lösung habe ich jetzt nicht für Dich.
Aber Du solltest vielleicht bedenken:
Zitat
Wenn nun irgendwo (HookCallback der user32.dll) die Maus länger als 2 Sekunden betätigt wird öffnet sich die Form und der Anwender kann das Objekt in die Form ziehen und dort "droppen"
Ist das eine Anforderung, oder eine Idee von Dir?
Ich würde eher den User das Fenster vorher selbst öffnen lassen - ich würde mich jedenfalls herzlich bedanken, wenn ich ein Objekt irgendwo anders hin draggen will, dann plötzlich eine Form aufploppt und sich über mein eigentliches Zielfenster legt...
ich schätze mal, Du musst einen Konstruktor von ManagementClass benutzen, dem Du ein ManagementScope übergeben kannst, und in diesem ManagementScope den anderen Rechner angeben.
das ist ja mal eine interessante Diskussion - zu der ich jetzt auch noch was beitragen möchte:
Zitat von Palin
Sondern eher darum ob es nicht vielleicht sinnvoll ist, ihn erst mal die Frage zu beantworten, die er zu den Arrays hat und ihn dann noch einen Anderen Weg aufzuzeigen. Anstatt um es vereinfacht wider zu geben zu sagen: „Arrays sind doof benutze Listen“.
Exakt. Genau meine Meinung
Abgelöst vom konkreten Beispiel möchte ich das noch etwas verallgemeinern. Ich habe in meiner langjährigen Zeit als Helfer es meistens so gehalten (oder es zumindest versucht):
Wenn es explizite Fragen gibt, versuche ich immer, diese auch zu beantworten - teilweise sogar im Nachhinein, wenn schon bessere Lösungen genannt wurden.
Gerade einem Anfänger nutzt es meist wenig, bzw. ist es vermutlich auch abschreckend, wenn man einfach nur sagt, Dein Ansatz ist schlecht, mach es lieber anders. Damit hilft man am Ende zwar auch dem Fragesteller ans Ziel - trotzdem sollte ihm IMO erst einmal mit seinen aktuellen Verständnisproblemen geholfen werden.
Gleichwohl darf natürlich der Hinweis auch nicht fehlen, das es wesentlich bessere Ansätze gibt. Warum diese Ansätze nun besser sind, kann der Fragesteller (wieder gerade, wenn es sich um einen Anfänger handelt) aber erst verstehen, wenn er sein ursprüngliches Problem verstanden hat - auch wenn die Lösung weit davon entfernt ist, gängig oder ideal zu sein.
Denn dann wird er selber sehen und beurteilen können, das er auf dem Holzweg war, und mit einem anderen Ansatz besser fährt.
Der beste Lerneffekt wird IMO also dadurch erzielt, erstmal das vorhandene Problem zu durchleuchten. Dann aber auch gleichzeitig dazu anzuregen, sich über eine bessere Lösung Gedanken zu machen, und dabei auch gleich einen Stups in die richtige Richtung zu geben (allerdings ohne ihm dabei die Lösung vorzukauen - Stichwort Fisch).
das @ gehört meiner Ansicht nach nur vorangestellt, wenn man tatsächlich Schlüsselwörter aus C# als Variblenname verwendet.
In Sollte man Keywords als Identifier verwenden? habe ich mal beschrieben, wann so etwas sinnvoll ist. In allen anderen Fällen sollte man davon die Finger lassen.
In den wenigsten realen Fällen ist das Performance-Problem die UI-Technologie - sondern der Code dahinter.
Ja, das mein ich auch.
Es sei denn es ist schlecht programmiert, z.B. können gerade im Bereich WinForms völlig mit Controls überladene Fenster oder nicht freigegebene Objekte aus System.Drawing (Pens, Brushes, Fonts etc. - dahinter liegen unverwaltete GDI+-Objekte, deshalb unbedingt alle selbst erzeugten disposen!) schon zu Problemen mit der Performance führen.
Zitat von BlackSimon
Evtl. reicht es auch einfach aus die WinForms-Anwendung performanter zu machen.
Wenn Du rausfinden willst, wo's wirklich hängt, dann schau mal mit nem Performance-Profiler. Da siehst Du genau wieviel Zeit wo verbraucht wird.
Kann ich denn z.B. sämtliche Methodenaufrufe von WinForms so übernehmen wie sie sind?
Kommt darauf an was Du damit meinst - aber vermutlich eher nicht.
Wenn Deine Anwendung eine saubere Schichtentrennung hat, ist das unter Winforms normalerweise mit MVC oder MVP umgesetzt. Dann kannst Du die Models und Businesslogik 1:1 übernehmen.
Was neu gemacht werden muss, sind auf jeden Fall die Views, die werden in WPF mit XAML umgesetzt. Und daran bindet man dann ViewModels, und nennt das ganze dann MVVM.
Das bedeutet, dass auch eventuelle Controller bzw. Presenter nicht mehr richtig passen werden. Was dort implementiert ist und mit der Businessschicht kommuniziert, sollte dann entsprechend MVVM auch in den ViewModels umgesetzt werden.
Den Timer von WinForms gibt es z.B. nicht mehr in WPF, als Komponente.
Richtig. Wenn Du einen solchen Timer in einer tieferen Schicht benutzt, ist das im Prinzip schon ein Designfehler.
In WPF gibt es den DispatcherTimer, der funktioniert ähnlich - sollte aber entsprechend auch nur auf der obersten Ebene verwendet werden. Es gibt aber für tiefere Schichten auch Time, die von der UI-Technologie unabhängig sind, z.B. System.Threading.Timer und System.Timers.Timer.
Ich würde Dir persönlich empfehlen, Dich erst mal ein wenig in WPF/MVVM einzuarbeiten, bevor Du an die Portierung eines bestehenden Projektes gehst, bis Du Dir ein gutes Grundverständnis der Technologie erarbeitet hast.
wie viel Code Du fehlerfrei übernehmen kannst, hängt ganz davon ab, wie sauber in der Forms-Anwendung die Schichten getrennt sind.
Wenn die Schichtentrennung optimal umgesetzt ist, musst Du nur das UI neu schreiben.
Wenn sich allerdings irgendwelcher UI-Kram nach unten durchzieht oder Logik (die nicht reine UI-Logik ist) in der UI untergebracht ist, wird es eben aufwändiger.
Das Problem was ich gefunden habe ist, daß "PropertyChanged" in Data immer null ist wenn
"OnPropertyChanged(...)" aufgerufen wird.
Kann ich nicht bestätigen. Der PropertyChanged-Krempel funktioniert wunderbar. Das hab ich gerade ausprobiert.
Dir fehlt in den Textbox-Bindings ein NotifyOnSourceUpdated=True, sonst wird das SourceUpdated-Event nicht ausgeführt.
Im SourceUpdated-Eventhandler (bei dir die Methode mit dem aussagekräftigen Namen "x" reicht dann folgendes:
private void x(object sender, DataTransferEventArgs e)
{
var box = (sender as TextBox);
if(box != null)
box.Background = Brushes.Green;
}
Microsoft betont, dass der Einsatz von nicht ausgereifter Gesichtserkennung, die beispielsweise bei Frauen und dunkelhäutigen Personen sehr ungenau arbeiten, nicht zielführend sei. Das Unternehmen arbeite daran, das zu verbessern.
Diese Passage steht ja nun n einem ganz anderen Kontext, als die Hinweise auf die Gefahren der Gesichtserkennung.
Ich interpretiere das so:
- Zunächst mal wird auf die Gefahren und die Notwendigkeit einer Regulierung ingewisen.
- Im Anschluss wird nachgeschoben, dass ferhleranfällige/ungenaue Algorithmen ohnehin nicht zielführend sind, selbst mit einer entsprechenden Regulierung. Und genau das soll verbessert werden. Die Notwendigkeit einer sinnvollen Reguilierung wird dabei aber nicht angezweifelt.
setz mal das request.KeepAlive = false, bevor Du den Request abschickst. Im Nachhinein bringt das nichts mehr. Dann bleiben vermutlich noch Verbindungen offen - FTP-Server mögen das oft nicht so gerne.
Laut Doku wird sogar eine InvalidOperationException geworfen, wenn KeepAlive nach Aufruf von GetResponse noch geändert wird wird. Die müsstest Du mit dem Code eigentlich für jede Datei bekommen.
Zusätzlich noch eine Anmerkung:
using (Stream ftpStream = request.GetResponse().GetResponseStream())
Durch dieses using wird zwar der Stream disposed, aber nicht die WebResponse.
Das sollte zwar in diesem Zusammenhang keine Rolle spielen - besser wäre es trotzdem, wenn Du Close oder Dispose auf der Response aufrufst. Der ResponseStream wird dadurch dann mit entsorgt.