Laden...
Avatar #avatar-2627.gif
herbivore myCSharp.de - Experte
freiberuflicher Informatiker Berlin Dabei seit 11.01.2005 49.485 Beiträge
Benutzerbeschreibung
Die Threads und Beiträge, die ich für besonders interessant halte, findet man durch Eingabe in die Forensuche von "1000 Worte" als Schlüsselworte und "herbivore" als Benutzernamen.

Forenbeiträge von herbivore Ingesamt 49.485 Beiträge

10.12.2014 - 11:19 Uhr

Hallo Dolce,

meinst du mit Cache die Zwischenablage?
[EDIT]Nach positiver Antwort (s.u.) auf die Frage, habe ich den Titel entsprechend angepasst[/EDIT]

In vielen Programmen kann man den Text der Textbox mit Ctrl-A markieren. Wenn nicht, dann mit Pos1 gefolgt von Shift-Ende.

herbivore

09.12.2014 - 21:23 Uhr

Hallo Sebastian.Lange,

du irrst. Damit wir nicht weiter spekulieren müssen, habe ich es ausprobiert. Wenn man das folgende Testprogramm startet (und es im Arbeitsverzeichnis eine Bitmap x.bmp gibt), bekommt man genau den beschrieben Fehler und zwar beim Aufruf von Save:

Fehlermeldung:
Ausnahmefehler: System.Runtime.InteropServices.ExternalException: Allgemeiner Fehler in GDI+.
bei System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
bei App.Main() in tmp.cs:Zeile 15.

Löscht man die Zeile fs.Close(); oder kommentiert sie aus, verschwindet der Fehler.

Es ist also so, wie Spyke und ich von Anfang an gesagt haben.

using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

static class App
{
   public static void Main ()
   {
      FileStream fs = new FileStream ("x.bmp", FileMode.Open);
      Image img = Image.FromStream(fs);
      fs.Close();

      MemoryStream ms = new MemoryStream();
      img.Save(ms, ImageFormat.Bmp);
      ms.Close ();
   }
}

herbivore

09.12.2014 - 19:47 Uhr

Hallo Sebastian.Lange,

hast du schon mal (testweise) versucht, deine Klassen so zu schreiben, wie die Third Party Components es machen? Und geht es dann?

Wenn es dir gelingt eine (äußere und innere) Klasse zu7 schreiben, mit der es im Designer funktioniert, kannst du schrittweise versuchen, sie wieder in die Richtung zu ändern, wie du es gerne hättest und schauen, wie weit zu damit kommt, bzw. welche Änderung den Designer aus dem Tritt bringt.

Möglicherweise ist es nur eine Kleinigkeit an deinen momentanen Klassen, die den Designer stört. Dann würde mit eben diesem kleinen Zugeständnis die Möglichkeit bestehen, relativ dicht an den von dir gewünschten (Ideal-)Zustand zu kommen.

herbivore

09.12.2014 - 19:35 Uhr

Hallo Sebastian.Lange,

ich hatte gesehen, wo der Fehler auftritt, aber wenn der Stream geschlossen ist, kann es potenziell bei jeder Operation knallen, denn man weiß ja nicht, wann GDI versucht auf den (geschlossenen) Stream zuzugreifen.

Beim Speichern werden alle Pixeldaten benötigt. Das ist durchaus ein Augenblick, bei dem es wahrscheinlich ist, dass (erneut) aus dem Input-Stream gelesen werden muss. Entsprechend kann nach dem Laden geschlossene Stream durchaus die Ursache für das Problem beim Speichern sein.

Auf jeden Fall sollte Gh0st21 seinen Code zu umstellen, dass der Stream offen bleibt. Zum einen ist das sowieso richtig(er) und sicherer. Und wenn dadurch der Fehler behoben ist, brauchen wir nicht weiter spekulieren.

herbivore

09.12.2014 - 19:33 Uhr

Hallo zusammen,

grundsätzlich geht es mir ähnlich. Lesen ist meist effektiver. Aber gerade bei ganz neuen Themengebieten kann es wirklich angenehm sein, sich den Einstieg erklären zu lassen.

Um etwaiger Langatmigkeit zu begegnen, lade ich mir das Video wenn möglich herunter, damit ich es schneller abspielen kann. Teilweise kann man Videos (z.B. mit VNC) mit 1,5facher Geschwindigkeit abspielen, ohne dass man das Gefühl hat, dass besonders schnell gesprochen wird. Wenn man noch schneller stellt, muss man sich mehr konzentrieren, aber bleibt dadurch auch mehr bei der Sache und die Gedanken schweifen weniger und gleichzeitig steigt das gefühlte Interesse.

Andersherum stelle ich mir schnell sprechende Engländer gerne auch mal etwas langsamer.

Außerdem kann man bei einem heruntergeladenen Video verzögerungsfrei vor und zurückspringen springen und so gezielt uninteressante Abschnitte überspringen oder nicht auf Anhieb verstandenes nochmal schauen, ohne lange fummeln zu müssen.

Und man kann das Video für einen Schnelldurchlauf auch mit 10facher Geschwindigkeit abspielen, um zu sehen, was noch alles passiert (dann freilich ohne Ton).

herbivore

09.12.2014 - 19:19 Uhr

Hallo Gh0st21,

der Stream muss offen bleiben, so steht es auch in der MSDN Doku:

Der Stream muss für die Lebensdauer der Image geöffnet bleiben.

Ist immer gut, wenn man mal in die Doku schaut, besonders wenn irgendwas nicht funktioniert.

herbivore

08.12.2014 - 19:38 Uhr

Hallo Spyke,

typischerweise findet man die Differenzen zwischen zwei Texten bzw. zwei Zeilen, indem man das Longest common subsequence problem löst.

herbivore

07.12.2014 - 12:56 Uhr

Hallo Sebastian.Lange,

Der Designer ignoriert die 2. Child Ebene(obwohl er das Test Property als Liste problemlos verarbeitet.

mit der Property als Liste meinst du vermutlich, eine Property vom Typ List<T> (egal mit welchem konkreten T). Ich denke, das zeigt die Problematik. Die Liste kann gesetzt werden, aber warum sollten ihre Properties (z.B. List.Capacity) gesetzt werden (können)? Ich finde es also nicht ganz unverständlich, wenn nur die Properties auf der ersten Ebene gesetzt werden können.

Als Lösung sehe ich zwei Möglichkeiten. Entweder, wie du sagst, eine Klasse (direkt oder als Wrapper) verwenden, die alle zu setzenden Properties direkt enthält. Oder ein Klasse, bei der alle geschachtelten Properties über den Konstruktor gesetzt werden können (vorausgesetzt der Designer erlaubt Konstruktoren mit Parametern).

herbivore

06.12.2014 - 19:02 Uhr

Hallo kkirchhoff,

bevor du gar keine Antwort bekommst, wenigstens noch der Hinweis auf [FAQ] Programm läuft in anderer Umgebung nicht (richtig). Du solltest mal schauen, welche der Informationen (insbesondere zum Auffinden der Fehlerursache) sich auf deinen Fall anwenden lassen.

herbivore

05.12.2014 - 17:37 Uhr

Hallo schui,

wie Programmierhans schon gesagt hat, gehören Delegates und Events zu den Grundlagen. Diese sollte/muss man beherrschen, bevor sich an weitergehendes wie WPF & Co macht.

Wenn dir die Begriffe unbekannt sind, ist das nicht ehrenrührig. Du kannst sie ja einfach nachschlagen. (Beachte dazu bitte [Hinweis] Wie poste ich richtig? Punkt 1.1.

Wichtiger als bestimmte Technologien finde ich allerdings, wenn du dich mit Konzepten beschäftigst, z.B. Softwarearchitektur, Prinzipien der Softwareentwicklung (DRY; KISS; YAGNI, ...), Algorithmen und Datenstrukturen u.ä.

Datenbanken sind auch ein wichtiges Feld. Aber was du brauchst, hängt von deinen zukünftigen Aufgaben ab. Ohne die zu kennen, ist es schwer bis unmöglich, etwas genaues zu raten.

Wenn du dich tief einarbeiten willst, musst du früher oder später ohnehin in alle genannten Bereiche schauen.

Generell gelten auch in deinem Stadium der Einarbeitung noch die Tipps aus [FAQ] Wie finde ich den Einstieg in C#?

Erwarte von uns keinen Lernplan. Dazu sind die Menschen, die Anforderungen und auch die Lernstile zu unterschiedlich. Was für den einen das wichtigste überhaupt ist, spielt für den anderen keine Rolle. Letztlich musst du deinen Weg selber suchen und finden. Anregungen dazu hast du bereits erhalten. Damit solltest du nun aus eigener Kraft weiterkommen.

herbivore

05.12.2014 - 13:12 Uhr

Hallo steffen_dec,

Kann es sein dass es bei Verknüpfungen auf dem Desktop ähnlich ist?

hinter .NET steckt oft Win32. .NET ist dann "nur" ein Wrapper und verhält sich im wesentlichen, wie die zugrundeliegenden Funktionen und Mechanismen von Win32 bzw. Windows selbst. Insofern ja, dass kann gut sein, dass für den Desktop die gleichen Auswahlkriterien gelten.

herbivore

04.12.2014 - 13:00 Uhr

Hallo arueger,

wenn auf dem Form nur das Label ist, hilft DockStyle.Fill durchaus. Dadurch nimmt das Label immer die gesamte Fläche (der ClientArea) des Forms ein. Und für das Label kann man dann mit Label.TextAlign ContentAlignment.MiddleCenter den Text zentrieren.

Wenn noch andere Controls auf dem Form enthalten sind, kann man ein TableLayoutPanel verwenden. Das Verhalten der Zellen bei Größenänderungen des Forms können gezielt festgelegt werden und die Ausrichtung des Inhalte der einzelnen Zellen auch.

herbivore

04.12.2014 - 12:54 Uhr

Hallo steffen_dec,

manchmal ist es schon verwunderlich, nach welchen Regeln Windows bestimmt, welches das "beste" Icon ist. Ich habe das nie vollständig durchschaut.

ohne jetzt ein eigenes kleines Icon erstellen zu müssen?

Du musst kein extra Icon erstellen, sondern kannst die gewünschte Auflösung aus dem bestehenden Icon extrahieren. Dazu gibt es den Icon-Konstruktor (Icon, Int32, Int32) oder (Icon, Size).

herbivore

04.12.2014 - 12:40 Uhr

Hallo SeriouslyNot,

aus [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke):

Databinding: Zugriffe auf gebundene Daten

Nicht nur Zugriffe auf Controls selbst müssen aus dem GUI-Thread erfolgen. Auch alle Zugriffe auf andere Objekte/Daten müssen aus dem GUI-Thread erfolgen, nachdem diese mittels Databinding an Controls gebunden wurden. Das heißt, man kann durchaus eine aufwändige Liste in einem Worker-Thread füllen, aber sobald diese Liste an ein Control gebunden wurde, was natürlich im GUI-Thread erfolgen muss, müssen auch alle weiteren Zugriffe auf die Liste und/oder darin enthalte Objekte aus dem GUI-Thread erfolgen.

Beim Rebind befindest du dich (vermutlich) wieder im GUI-Thread, aber auch der Zugriff auf die gebundenen Daten muss im GUI-Thread erfolgen. Andersherum formuliert: Daten auf die man in einer (separaten) Task zugreifen will, dürfen noch nicht oder nicht mehr gebunden sein.

Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1. Alle Fragen zum Thema Zugriff auf GUI-Elemente und gebundene Daten werden in der FAQ ausführlich behandelt.

herbivore

04.12.2014 - 12:18 Uhr

Hallo Palin,

rein technisch ist dein erster Absatz richtig, konzeptionell nicht. Begründung oben.

Beim zweiten Absatz gehst du von falschen Voraussetzungen aus. Hier wird ein Interface gebraucht. Die abstrakte Klasse hat dagegen eine reine Hilfskonstruktion, die vom Implementierer des Interfaces optional benutzt werden kann (und selbst das funktioniert nicht in alle Situationen s.o.), aber nicht benutzt werden muss.

Die wichtigste Einschränkung, von abstrakten Klassen gegenüber Interfaces - die du hier anscheinend übersiehst oder für nicht relevant hältst - ist, dass eine Klasse zwar mehrere Interfaces implementieren, aber nur von maximal einer Oberklasse erben kann. Deshalb kann man Interfaces nicht einfach durch abstrakte Klassen ersetzen.

Ich hoffe, wir können diesen Nebenkriegsschauplatz jetzt verlassen. Letztlich muss sich sowieso jeder Leser sein eigenes Bild machen. Die Argumente liegen auf dem Tisch.

herbivore

04.12.2014 - 01:09 Uhr

Hallo Palin,

ich schließe mich Uwe81 an. Eine Basisklasse ersetzt hier das Interface nicht. Die meisten Gründe hat Uwe81 genannt(*). Dazu kommt noch, dass es Fälle gibt, in denen die Basisklasse absichtlich nicht das gesamte Interface abdeckt. Dann würde die Basisklasse das Interface gar nicht (vollständig) implementieren, sondern z.B. nur ein paar Member davon. Erst die konkreten Unterklassen würden dann das (vollständige) Interface implementieren. Oder als Code ausgedrückt:

public interface IStep {...}
public abstract class StepBase  {...}
public class Destination : StepBase, IStep {...}

Davon abgesehen hattest du ja selbst geschrieben, dass Interfaces für etwas (leicht) anderes gedacht sind als Basisklassen. Schon deshalb sollte man aus dem einen nicht das andere machen und auch nicht umgekehrt.

Interface und Basisklasse ergänzen sich, aber die ersetzen sich nicht.

herbivore

(*) Schau sie dir noch mal an. Sie sind stichhaltig! Du hast sie nicht entkräftet und schon gar nicht widerlegt. Man kann auf das Interface nicht verzichten oder sollte es zumindest nicht, nur weil man eine Basisklasse für das Standardverhalten anbietet.

04.12.2014 - 00:52 Uhr

Hallo ZeroQool,

wie ein Vertrag genannt wird, ist nebensächlich. Wichtig ist, was darin vereinbart ist. In Deutschland besteht Vertragsfreiheit. Also kann man - im Rahmen der Gesetze - alles vereinbaren was man möchte. "Man" sind in dem Fall die beiden Parteien, die den Vertrag schließen. Was vereinbart werden soll, kannst du eigentlich nur in einem Gespräch mit dem Kunden klären. Wie sollen wir wissen, was der Kunde will und/oder was du willst.

Ob eines eine Gewährleistung gibt, hängt davon ab, was für ein Vertrag für die ursprüngliche Erstellung der Software geschlossen wurde. Bei einem Kaufvertrag, z.B. bei Standard-Software, schuldet man eine magelfreie Sache. Bei einem Werkvertrag schuldet man den Erfolg, also das (mangelfreie) Werk. Bei einem Dienstvertrag schuldet man nur das ernsthafte Bemühen um einen Erfolg. Wenn der (innerhalb der vereinbaren Arbeitszeit) nicht eintritt, ist es das Pech des Auftraggebers.

Unter Wartung versteht man sowieso nicht nur die Behebung von (von Anfang enthaltenen) Fehlern, sondern auch nötige Anpassungen aufgrund von geänderten Rahmenbedingungen oder Kundenwünschen. Es kann also schon Sinn machen, einen Wartungsvertrag abzuschließen.

Insgesamt würde ich in der Tat sagen, dass es ein bisschen durcheinander geht. Ich wüsste ohne eine konkretere Beschreibung von dem, was du oder dein Kunde will, jedenfalls erstmal nichts weiter zu sagen.

herbivore

03.12.2014 - 19:54 Uhr

Hallo briloner,

das .NET Framework kann das wohl nicht. Wenn du das willst, brauchst du wohl eine externe Bibliothek, z.B. LibTiff.Net.

CYMK-TIFF-Bilder zu bearbeiten ist eine Standard-Aufgabe, zu der du alle nötigen Infos im Netz findest. Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1.

herbivore

03.12.2014 - 15:36 Uhr

Hallo tom-essen,

solange es hier um Unterklassen geht, die genau ein Interface implementieren und außerdem von keiner anderen Oberklasse erben müssen/sollen, ist alles in Ordnung. Dann ist das Vorgehen auch sinnvoll. Redundanzen sollten vermieden werden und werden es hierdurch. Eine wesentliche Aufgabe von Basisklassen ist die Redundanzvermeidung.

Problematisch wird es, wenn eine (Unter-)Klasse mehrere Interfaces implementieren soll. Zum Beispiel werden im Zuge von DataBinding oft INotifyPropertyChanged und IDataErrorInfo gleichzeitig implementiert. Wenn man dafür eine NotifyPropertyChangedBase und eine DataErrorInfoBase Klasse anbieten würde, müsste sich der Implementierer der Unterklasse entscheiden, welche davon er verwendet. Die andere ist dann für ihn mehr oder minder nutzlos (um so mehr, wenn sie abstrakt ist). Er kann nicht von beiden Klassen erben, weil C# keine Mehrfachvererbung unterstützt (als "Ersatz" gibt es gerade Interfaces).

Das gleiche Entscheidungsproblem taucht auf, wenn aus die Unterklassen aus anderen Gründen von einer bestimmten Oberklasse erben müssen und zusätzlich ein Interface implementieren soll. Dann kann aus dem gleichen Grund von der zum Interface gehören Basisklasse nicht geerbt werden.

Da man nie weiß, ob eine Unterklasse später noch ein weiteres Interface implementieren oder von einer anderen Basisklasse erben soll, ist das Vorgehen, zu einem Interface auch eine Basisklasse anzubieten, leider nicht so universell, wie man es sich wünschen würde.

Auf der sicheren Seite ist man, wenn man zu jedem Interface eine Hilfsklasse anbietet, die die nötigen Methoden zum Aufrufen (und nicht zum Erben) anbietet. Das könnte z.B. auch eine statische Klasse sein, deren Methoden das zu bearbeitende (Interface-)Objekt per Parameter bekommt.

Der Nachteil von Hilfs-(im Gegensatz zu Basis-)Klassen ist, dass man in den konkreten (Unter-)Klassen den Implementierungsaufwand hat, um die Hilfsmethoden aufzurufen. Aber dafür funktionieren sie immer und man kann sie in allen (zukünftigen) Situationen garantiert einsetzen.

herbivore

03.12.2014 - 15:18 Uhr

Hallo briloner,

ob Tiff oder nicht. Erstmal musst du aus den Bildern Bitmap-Objekte machen.

Wenn du dann mit Graphics.FromImage.DrawImage ein an bestimmten Stellen transparentes Bild über anderes bestehendes Bild zeichnest, dann bleibt an den transparenten Stellen das ursprüngliche Bild sichtbar. Nach deiner Beschreibung müsste das, das sein, was du willst.

herbivore

03.12.2014 - 11:35 Uhr

Hallo h1ackmann,

das geht so nur, wenn alle Boxen sich direkt im Form befinden. Boxen die sich in z.B. einer GroupBox befinden, werden so nicht erfasst. Daher der Hinweis von t0ms3n rekursiv zu suchen.

Generell wird das Thema in [FAQ] Variablennamen zur Laufzeit zusammensetzen / Dynamisches Erzeugen von Controls (hier: vor allem, aber nicht nur der Abschnitt: "Kann man nicht direkt auf die Controls-Collection zugreifen?") behandelt und andere Herangehensweisen aufgezeigt.

Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1 und 1.1.1.

herbivore

02.12.2014 - 17:41 Uhr

Hallo zusammen,

aus meiner Sicht würde es vom Grundgedanken her reichen, sich die Cursorposition zu merken, ab dort neu " EUR" zu auszugeben und den Cusor wieder an die gemerkte Position zu setzen. Zumindest, wenn an die Zahl nur am Ende Ziffern angefügt werden können. Wenn am Ende auch Ziffern gelöscht werden können, müsste man " EUR " ausgeben. Wenn innerhalb der Zahl editiert werden kann, würde ich nach jeder einzelnen Änderung die jeweils die ganze Zahl + " EUR " ausgeben.

Man kann auch Pufferbereiche verschieben/kopieren. Aber ich denke, für das hier gewünschte wird es einfacher sein, den zu verschiebenden Text einfach neu auszugeben.

herbivore

01.12.2014 - 12:31 Uhr

Hallo mcsas,

es scheint leider keine ResetBackgroundColor-Methode zu geben. Hast du schonmal versucht, die BackgroundColor auf Color.Empty zu setzen?

herbivore

01.12.2014 - 11:46 Uhr

Hallo Sebastian.Lange,

man muss zwischen der rechtlichen Situation und der Durchsetzbarkeit der Rechte in der Praxis unterscheiden. Rechtlich wäre es möglich, dass man seinen Quellcode veröffentlicht, aber denjenigen, die ihn herunterladen, nur die einfache Nutzungsrechte einräumt, was insbesondere bedeuten würde, dass sie den Code nicht kopieren und nicht weitergeben dürfen. Tut jemand das trotzdem, könnte man ihm eine Abmahnung schicken und ihn verpflichten, eine Unterlassungserklärung abzugeben. Tut er das nicht, kann man ihn verklagen. Nur weiß man in der Praxis normalerweise nicht, wer gegen die Lizenz verstoßen hat und selbst wenn man es weiß, lohnt der Aufwand, dagegen vorzugehen, den Nutzen meistens nicht. In diesem Sinne verliert man bis zu einem gewissen Grad die faktische Kontrolle über den Code, wenn man ihn veröffentlicht.

Aber die Rechte am eigenen Code verliert man durch eine reine Veröffentlichung nicht. Insbesondere bleibt man auch bei Verwendung von üblichen Open Scource Lizenzen Herr über die eigene Versionsverwaltung. Es besteht keine Verpflichtung, Anderen (schreibenden) Zugriff darauf zu gewähren. Andere können den Code kopieren, ändern und selbst wieder veröffentlichen, aber der eigene Code-Stand ist dadurch nicht betroffen, wenn man das nicht explizit will. Und da man auch technisch in der Lage ist, die Zugriffsrechte entsprechend zu setzen, hat man hier nicht nur die rechtliche, sondern auch die faktische Kontrolle und behält sie auch (solange der Server nicht gehackt wird).

Und man kann eben den eigenen Code unabhängig von der Veröffentlichung weiterhin nach Belieben nutzen, also z.B. unter anderer Lizenz in kommerziellen Anwendungen einsetzen. Auch unterliegt man keiner Verpflichtung, eigene Veränderungen am eigenen Code ebenfalls zu veröffentlichen. Man kann also z.B. für einen Kunden Anpassungen vornehmen und sich bezahlen lassen und weder man selbst noch der Kunde muss diesen Codestand veröffentlichen.

Das gilt natürlich alles nur, solange hier ausschließlich eigener Code im Spiel ist. Haben Andere zum eigenen Projekt Codeteile unter einer der üblichen Open-Source-Lizenzen beigetragen, dann hat man an diesen Codeteilen natürlich nur die Rechte, die einem von den Contributoren eingeräumt wurden, ist also nicht mehr frei. Dazu hatte ich oben schon etwas geschrieben.

Kurz gesagt: Auch bei einer Veröffentlichung behält man selbst alle Rechte am eigenen Code. Man muss sich aber im klaren sein, dass man bestimmte Rechte faktisch nicht durchsetzen können wird. Das bedeutet aber keine totale Aufgabe aller Rechte. Den anderen Teil der Rechte kann man durchaus auch praktisch nutzen und durchsetzen. Details dazu habe ich bereits genannt.

herbivore

30.11.2014 - 15:38 Uhr

Hallo Pain,

Die files sollen nach Möglichkeit auch alle parrallel verarbeitet werden.

die optimale Anzahl der (echt) parallele Aufgaben hängt mehr von den Architektur des Rechners und seiner Ressourcen (Anzahl Cores, Anzahl IO-Kanäle usw.) ab und natürlich von der Art der Aufgaben, aber weniger von der Größe der Eingabemenge. Der Versuch, auf Biegen und Brechen alles anstehenden Eingaben parallel zu bearbeiten, kann und wird die Gesamtlaufzeit eher verlängern.

Wenn die Aufgaben CPU-lastig sind, liegt die optimale Anzahl typsicherweise bei oder in der Nähe der Anzahl der vorhanden Cores.

Das parallele Einlesen von mehreren (großen) Dateien von einer einzelnen mechanischen Festplatte ist dagegen meistens eher kontraproduktiv, siehe Multithreaded File I/O, insbesondere die Diagramme auf der zweiten Seite.

Aus meiner Sicht macht es Sinn, die optimale Anzahl von Workern zu ermitteln/abzuschätzen, dann diese Anzahl an Worker zu erstellen bzw. zu verwenden. Die Aufgaben werden dann in eine zentrale Queue gestellt, aus der sich jeder Worker/Consumer in einer (quasi) Endlosschleife die jeweils nächste Aufgabe herausholt und bearbeitet.

herbivore

30.11.2014 - 13:24 Uhr

Hallo telfa,

im Reflector sieht es wirklich so aus, als würden übergeordnete ReadOnly-Einstellungen per ODER verknüpft. Spricht, wenn ein übergeordnetes ReadOnly true ist, kann ein unterordnete nicht false sein.

Also: Works as designed.

herbivore

29.11.2014 - 14:06 Uhr

Hallo

ich verstehe deine Frage nicht genau oder sie geht von falschen Annahmen aus.

Es gibt DataGridViewCell.ReadOnly, womit man einzelne Zellen schützen kann.

Außerdem steht in Wie lege ich in einem DataGridView bestimmte Zellen als schreibgeschützt fest?:

Somit kann der Schreibschutz für das gesamte Steuerelement, für bestimmte Spalten und Zeilen sowie für einzelne Zellen festgelegt werden.

Oder meinst du, das ganze DGV readonly setzen und dann eine einzelne Zelle davon ausnehmen? Kann sein, dass das so nicht geht. Es kommt darauf an, wie der Schreibschutz der einzelnen Ebenen (Grid, Zeile, Spalte, Zelle) verknüpft wird. Wenn es eine ODER-Verknüpfung ist (wovon ich mal ausgehe), gewinnt natürlich immer der Schutz, nicht dessen Aufhebung.

herbivore

29.11.2014 - 11:15 Uhr

Hallo MacGuyver,

was passiert, wenn du das Update deinstallierst? Eine Reparaturinstallation durchführst? Alles neu installierst?

herbivore

29.11.2014 - 10:58 Uhr

Hallo Larkem,

ob man zwischen (Zahn)Rad und Ritzel unterscheiden muss weiß ich nicht. Das hängt ein bisschen von den Umständen ab. Es sind ja beides Zahnräder. Vielleicht reicht da eine Klasse. Und solange du nur Zahnradpaarungen berechnest, brauchst du auch nicht unbedingt eine Klasse Getriebe. Hängt auch wieder von den Details ab.

Doch da du wohl noch am Anfang stehst, probiere doch mal beides aus (also einmal mit allen genannten Klasse und einmal nur mit der Klasse Zahnrad) und schau, welche Variante (für dich) verständlicher, übersichtlicher, klarer und eleganter ist. Bzw. welche der beiden Varianten die oben genannten Kriterien und zusätzlich auch das KISS-Prinzip und Don’t repeat yourself besser erfüllt.

Auch wenn du 50 Werte berechnen musst, läuft die Berechnung für jede Paarung vermutlich grundsätzlich gleich ab (also nach immer dem gleichen Grundschema). Das klingt dann schon sehr danach, dass man eine Liste (oder zwei Listen) übergibt und eine Ergebnisliste zurückbekommt. In der Methode würden dann alle Berechnungen per Schleife durchgeführt.

Allerdings sind wir hier dann wirklich bei [Hinweis] Wie poste ich richtig? Punkt 1.1.1. Mit den gegebenen Informationen und der weiteren Einarbeitung in OOP solltest du jetzt alleine weiterkommen (können).

herbivore

29.11.2014 - 00:36 Uhr

Hallo MrSparkle,

Du mußt natürlich auch bedenken, daß BoundingCircles gegenüber BoundingBoxes nicht nur performanter sind, aber dafür auch ungenauer.

das gilt so pauschal nicht. Es hängt u.a. von der Form der eigentlichen Objekte ab. Sind das z.B. alles kreisrunde Scheiben, dann sind BoundingCircles offensichtlich genauer (und nicht zu sagen exakt) als BoundingBoxes. Außerdem hängt es davon ab, wie man die BoundingBox bestimmt. Wenn man bei einem um 45° gedrehten Quadrat eine achsenparallele BoundingBox verwendet, wäre ein BoundingCircles ebenfalls genauer. Man kann also keineswegs pauschal sagen, ob BoundingCircles oder BoundingBoxes genauer sind. Es kommt immer auf die genauen Umstände und Details an.

herbivore

29.11.2014 - 00:22 Uhr

Hallo unconnected,

ohne genaue Aussagen, was Larkem will, ist es natürlich schwierig etwas genaues zu sagen. Aber gerade deshalb finde ich es ungünstig pauschal ein Dictionary zu empfehlen. Eine Liste geht ja noch in Ordnung, wenn alle Werte von gleichen Typ und auch sonst gleichartig sind, aber für ein Dictionary statt eines eigenen Objekts / einer eigenen Klasse muss man schon gute Gründe haben. Insbesondere wenn die Keys eines Dictionaries den Namen von Etwas entsprechen, woraus man auch eine Property machen könnte, dann spricht das eher für eine eigene Klasse.

herbivore

29.11.2014 - 00:11 Uhr

Hallo Larkem,

Ich hoffe, die Fragestellung ist nachvollziehbar.

ohne die Details zu kennen, ist beleibt vieles unklar/unsicher.

Übergibt man die alle oder wird eher auf globale Variablen zurückgegriffen?

Weder noch: Zusammengehörige Daten gehören in ein Objekt, als Member/Fields. Dies Objekt kann man dann per Parameter übergeben. Auch ein paar davon. Aber man würde weder 50 Parameter übergeben noch globale Variablen verwenden (globale Variablen gehören in die Mottenkiste).

Mit scheint die Frage doch sehr in Richtung [Hinweis] Wie poste ich richtig? Punkt 1.1.1 zu gehen. Ich halte es für ratsam, wenn du dich zunächst mit objektorientierter Programmierung beschäftigst. Schon alleine die Ansicht, dass es darum ginge, Abläufe zu programmieren, spricht dafür, dass du von der Programmierung eher eine prozedurale - und damit eine im C# Umfeld eher ungeeignete(!) - als eine objektorientierte Vorstellung hast. Möglicherweise hilft auch ein Blick in [FAQ] Wie finde ich den Einstieg in C#?

Oft werden Methoden sogar viel kürzer als eine Bildschirmseite sein. Aber es gibt auch Ausnahmen. Zum Beispiel macht es nicht viel Sinn, Methoden, die viele gleichartige und gleichwertige Operationen durchführen (z.B. alle Controls in einem Form zu erzeugen, namentlich InitializeComponent) in mehrere Teile aufzuteilen, nur damit sie weniger lang ist als eine Bildschirmseite. Wenn man InitializeComponent aufteilen wollte, dann eher durch eine logisch Strukturierung, z.B. durch die Verwendung von UserControls.

Kriterien, was in eine Methode zusammen gehört und was nicht (mehr), sind Single-Responsibility-Prinzip und Separation of concerns.

herbivore

28.11.2014 - 15:17 Uhr

Hallo Movementroboter,

naja, das würde ich schon per Schleife machen.

Wie zommi richtig sagt, sollte man zum Bearbeiten den String in eine char-Array umwandeln, dass dann bearbeiten und am Ende wieder einen String daraus machen.
Da du immer nur zwei benachbarte Zeichen (=Array-Elemente) vertauschen willst, kann man das auch mit einem einfachen Dreieckstausch tun.

String-Verarbeitung gehört allerdings zu den Grundlagen, die wir voraussetzen. Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore

28.11.2014 - 13:04 Uhr

Hallo Quaneu,

also bei mir geht das problemlos.

using System;
using System.Windows.Forms;

public class MyWindow : Form
{
   bool _modal;

   public MyWindow (bool modal)
   {
      _modal = modal;
      Text = "MyWindow";
      var ctrlCurr = new Button ();
      ctrlCurr.Dock = DockStyle.Fill;
      ctrlCurr.Text = "Open";
      ctrlCurr.Click += OpenClick;
      Controls.Add (ctrlCurr);
   }

   protected void OpenClick (Object sender, EventArgs e)
   {
      Form form = new MyWindow (!_modal);
      if (_modal) {
         form.ShowDialog ();
      } else {
         form.Show ();
      }
   }
}

public static class App
{
   public static void Main ()
   {
      Application.Run (new MyWindow (true));
   }
}

Wenn es bei dir nicht geht, siehe [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden.

BTW: Wie vermutlich vielen Lesern im Forum bekannt, würde ich empfehlen, gar keine modale Fenster zu verwenden, siehe z.B. Warten auf Schließen einer anderen Form [und warum man Dialoge nicht modal machen sollte].

herbivore

28.11.2014 - 11:01 Uhr

Hallo freak4fun,

BN_CLICK_ED_
ist die Benachrichtigung (Notification), dass der Button geklickt wurde. Die Nachricht (Message), um das Klicken auszulösen, heißt B_M__CLICK.

herbivore

27.11.2014 - 13:10 Uhr

Hallo AlexK,

treten hinter den Zahlen Bildstörungen auf, die von der Software als Bindestrich (Wordtrennung) interpretiert werden können?

Ansonsten bleibt mein Vorschlag, man nach den Einstellmöglichkeiten zu schauen.

Wenn du wüsstet, dass alle Zahlen immer sieben Ziffern lang sind, könntest du solche Umbruchfehler auch nachträglich korrigieren. Zumindest, wenn sie relativ selten sind, nicht mehrere Zahlen hintereinander betreffen und die Software keine Ziffern ganz verschluckt.

herbivore

27.11.2014 - 13:01 Uhr

Hallo AlexK,

keine Ahnung, wie verbreitet diese OCR-Bibliothek ist und ob sich damit hier jemand auskennt.

So wie ich das in dem Beispielcode auf der verlinkten Seite sehe, kommt man auch an die erkannten Worte. Dann kann dir der Umbruch der Zeilen egal sein.

Ansonsten kann ich mir vorstellen, dass es eine Einstellung gibt, ob für den Text Fließtext oder Text mit festen Umbrüchen angenommen werden soll. Schau mal in die Doku bzw. schau dir an, welche Member, insbesondere Properties, Methoden und Parameter der Methoden es in den Klassen gibt.

herbivore

27.11.2014 - 05:43 Uhr

Hallo DecaTec (ehemals exec), hallo zusammen,

ich bin gerade in c't auf folgenden Artikel gestoßen:

c't 25/14, S. 148
Dennis G. Jansen
[B]Das Recht am eigenen Code[/B]
Contributor License Agreements: Mehr Flexibilität zwischen Entwicklern und Open-Source-Projekten

Darin geht es um Vereinbarungen, die der ursprüngliche Entwickler eines Projekts vorab mit den Entwicklern schließt, die später etwas zum Projekt beitragen wollen (Contributor). Diese Vereinbarung nennt man Contributor License Agreements. Es ist also die Lizenz, unter der ein Entwickler zum Projekt beiträgt. Der Trick ist, dass man darin beliebiges vereinbaren kann, also sich z.B. an dem Code, der eingereicht wird, mehr Rechte einräumen lassen kann, als man hätte, wenn die Entwickler einfach unter den Bedingungen der normalen Open Source Lizenz, unter der das Projekt steht, beitragen würden. Wenn in den Contributor License Agreements entsprechendes vereinbart ist, kann man z.B. die Open Source Lizenz, unter der das Projekt steht, ändern, ohne jeden einzelnen Entwickler um Zustimmung zu fragen. Die einzelnen Entwickler haben dann die Zustimmung bereits dadurch gegeben, dass sie unter den Bedingungen der vereinbarten Contributor License Agreements zum Projekt beigetragen haben.

herbivore

27.11.2014 - 05:06 Uhr

Hallo ZeroQool,

welche Rechte an dem Quellcode will bzw. braucht denn der Kunde? Will er ihn nur zum eigenen/internen Gebrauch? Um ihn selber zu pflegen? Oder um beliebig viele Installationen hausintern vorzunehmen? Oder will er ihn, um den Code selbst oder daraus kompiliere Programme an Dritte zu vertreiben? Den Quellcode zu übertragen bedeutet nicht zwangsläufig, auch alle Rechte an dem Code (mit) zu übertragen. Ohne eine Antwort auf diese Frage, welche Rechte übertragen werden sollen, wird es schwer eine Antwort auf deine Frage zu geben.

Wenn der Kunde den Code und alle Rechte will, kannst du mal in Software Weiter-Verkauf durch Kunden, Source Codes offenlegen schauen. Da wurde dieser Fall bereits ausführlich besprochen.

herbivore

27.11.2014 - 04:56 Uhr

Hallo zommi,

Also wenn ich dich richtig verstehe, nutzt du lieber die Methode Match und iterierst nachfolgend über die CaptureCollection einer Group.

nö, nicht pauschal. Es kommt immer darauf an.

Wenn die Blöcke direkt aufeinanderfolgen müssen (wovon ich ausgegangen bin), würde ich es aber tatsächlich über Match+Captures machen. Wenn man Matches mit einem Pattern für nur einen Block benutzen würde, müsste man in diesem Fall \G benutzen (siehe Anker in regulären Ausdrücken), um sicherzustellen, dass die Matches direkt aufeinander folgen. Und das ginge wiederum nicht oder nur sehr umständlich, wenn man mit Lookarounds für den Rahmen arbeiten würde.

Wenn die Blöcke aber an beliebigen Stellen verstreut stehen können, dann wäre natürlich ein Pattern angebracht/erforderlich, der immer nur auf einen Block matcht.

Nunja, ich habe es lieber, wenn mein Regex bereits genau das zurückliefert, woran ich interessiert bin, und nicht in einer Group gekapselt ist.

Dem kann ich mich nicht anschließen. Generell mache ich es schon lieber, dass ich auf den gesamten Rahmen matche (also hier Header + Trennzeile + Inhalt + Trennzeile) und dann Gruppen für die Teile definiere, die ich brauche. Das ist auch das universellere Vorgehen, weil es auch funktioniert, wenn man mehrere Textteile aus einem Rahmen benötigt. Auch wenn man später zusätzliche Informationen benötigt, braucht man quasi nur Klammern an die richtigen Stellen im Pattern zu setzen. Man ist also auch flexibler.

Dass dein Pattern (ohne Singleline) funktioniert, hatte ich ja schon geschrieben.

herbivore

26.11.2014 - 21:30 Uhr

Hallo Nokinger,

(?:(?!-{50}).) matcht auf ein beliebiges Zeichen, es sei denn das Zeichen ist bereits das erste Zeichen der Trennzeile aus genau 50 Minuszeichen.

Du musst dir die Prüfung so vorstellen, dass der Zeiger zwischen zwei Zeichen steht, und zwar unmittelbar vor dem Zeichen, auf das der Punkt passen soll. Jedoch wird erst geguckt, ob Pattern in dem Lookaheadteil ab hier zu passen beginnt. Wenn ja, ist Schluss. Dann wird der Punkt gar nicht gematcht. Wenn nicht, dann passt der Punkt auf das Zeichen, aber das kann dann eben nicht der Beginn der Trennlinie sein. Genau wie man es will.

(?:.(?!-{50})) match auf ein beliebiges Zeichen, es sei denn, hinter dem Zeichen beginnt eine Trennzeile aus genau 50 Minuszeichen. Damit wird aber schon das letzte Zeichen vor der Trennlinie nicht mehr gematcht.

Du hast den Punkt sogar in den Lookahead geschrieben. Das ist erst recht Unsinn.

Der Lookbehind (?≤ABC\s:.**{50}) sagt, dass es eine Zeile geben muss, die (etwas vereinfacht gesagt) mit ABC beginnt, dann können beliebig viele beliebige Zeilen kommen (auch Trennzeilen) und dann am Ende eine Trennzeile. Der Lookbehind passt also überall, wo es eine Trennzeile gibt und irgendwo vorher eine Zeile, die mit ABC beginnt (die erste Zeile, in der Datei, die mit ABC beginnt reicht also). Der Lookbehind passt also auf alle Trennzeilen in der Datei, sofern vorher irgendwo eine Zeile steht, die mit ABC beginnt.

Es reicht übrigens nicht, das .* im Lookbehind durch .? zu ersetzen. Warum steht in RegEx kürzester Match [und die Gefahren von .*?]. Wenn man das . durch (?:(?!-{50}).)* ersetzt, geht es aber wieder. Allerdings ist ein Lookahead in einem Lookbehind vielleicht nicht mehr für jeden sofort zu durchschauen.

zommis Pattern funktioniert jedoch, sofern man nicht Singleline verwendet, also sofern der Punkt nicht auf Zeilenvorschübe passt.

herbivore

26.11.2014 - 19:10 Uhr

Hallo zommi,

Lookarounds nützen allerdings nichts, wenn sich mehrere Teile, die im Ergebnis enthalten sein sollen, mit Teilen abwechseln, die nicht enthalten sein sollen. Ist natürlich immer eine die Frage, wie man es sieht bzw. angeht. Ich verwende im folgenden einen Match, der alle Blöcke auf einmal matcht. Wenn man den Pattern so schreibst, dass er nur einen Block auf einmal matcht, dann geht es auch mit Lookarounds.

Hallo Nokinger,

im Grunde ist es doch ganz einfach. Man muss nach und nach aufschreiben, was für Zeichen kommen müssen und dürfen.

Zu erste kommt eine Zeile, die so aussieht:
\s?ABC\s*:.*

Dann eine erste Trennzeile:
-{50}

Dann beliebiger Text, der uns interessiert, also am besten als benannte Gruppe. Durch das (?s) bzw. RegexOptions.Singleline geht das auch über mehrere Zeilen hinweg:
(?<result>.*)

Dann eine zweite Trennzeile:
-{50}

Zusammen wäre das:
:\s?ABC\s*:.-{50}(?<result>.)-{50}

Das ganze soll sich (dreimal) wiederholen, also alles einklammern und den entsprechenden Quantifyer dahinter setzen:
(?:\s?ABC\s*:.-{50}(?<result>.)-{50}){3}

In den drei Captures der benannten Gruppe sind dann hübsch die drei Textteile, die dich interessieren.

Das würde schon funktionieren, hat aber noch einen Nachteil, nämlich dass beliebiger Text auch auf die Trennzeilen matchen würde. Also wollen wir nicht ganz beliebigen Text, sondern nur solchen, der keine Trennzeilen enthält, also statt .* besser:
(?:(?!-{50}).)*

Macht zusammen:

(?:\s?ABC\s*:(?:(?!-{50}).)-{50}(?<result>(?:(?!-{50}).))-{50}){3}

Das Ergebnis eines nicht trivialen Regex sieht zugegeben meistens etwas spröde aus, aber eine solchen Pattern Schritt für Schritt zu erstellen, ist doch wirklich einfach. Man muss eben wirklich ganz stur Schritt für Schritt vorgehen.

herbivore

24.11.2014 - 14:59 Uhr

Hallo Truusman,

verwende ein TableLayoutPanel.

herbivore

23.11.2014 - 09:05 Uhr

Hallo cayen,

was meinst du mit "vorher ausführen"? Meinst du, dass du nicht nur die zu testende Methode aufrufst, sondern auch eine Hilfsmethode, die dann den Wert liefert, der mit dem Rückgabewert der zu testenden Methode verglichen wird? Und wenn ja, wobei siehst du da ein Problem?

Oder meinst du Mocking? Also dass die zu testende Methode eine andere (Hilfs-)Methode aufruft, die bestimmte Werte liefert, so wie es für den Test der zu testenden Methode gerade erforderlich ist.

Bitte beachte in beiden Fällen vorsorglich [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore

23.11.2014 - 08:39 Uhr

Hallo Ryzo,

es sollte klar sein, dass du nicht der erste bist, der diesen Wunsch hat. Folgende Treffer habe ich mit der zweiten Suchanfrage, die mir eingefallen ist, innerhalb von einer Minute gefunden.

removing the empty gray space in datagrid in c#
DatagridView: Remove unused space?

Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 1.1. Und wenn klar ist, dass das Thema bereits behandelt wurden, bitte die Suchanfragen solange variieren, bis der Erfolg eintritt.

herbivore

22.11.2014 - 08:28 Uhr

Hallo Inderrupt,

ich denke, so ziemlich jedes Buch über Projektplanung bzw. Projektmanagement wird auch auf die Dokumentation während der Analyse- und Designphasen eingehen. Ob das dann immer Fachkonzept und DV-Konzept heißt, würde ich offen lassen, aber etwas vergleichbares wird wohl schon behandelt werden. Auch in den realen Projekten wird dann sehr unterschiedlich damit umgegangen. Ich kenne Projekte, in denen es die beiden Dokumente genau mit diesem Namen und diesen Funktionen gibt, aber auch andere.

Die Funktion der Dokumente finde ich zudem auch ohne Buch ziemlich klar. Einfach gesagt wird im Fachkonzept "die Funktionalität primär aus Sicht des Anwenders" beschrieben und im DV-Konzept aus IT-Sicht "die Aufgabenstellungen aus dem Fachkonzept [...] bezüglich den Datenstrukturen und Verarbeitungsschritten strukturiert und dokumentiert". Darunter wird im Detail natürlich sehr unterschiedliches verstanden und eine für alle realen Projekte allgemeingültige Definition wird es ohnehin nicht geben.

Nach meiner Erfahrung werden zur Erstellung meist normale Textverarbeitungsprogramme verwendet, natürlich mit entsprechenden Dokumentenvorlagen, die den Rahmen vorgeben. Ein einfaches Tool zum Erstellen einer Spezifikation findest du in DonkeySpecs - ein Tool für Spezifikationen (zumindest einen Teil davon) (bisheriger Name: RichSPEC).

herbivore

21.11.2014 - 22:26 Uhr

Hallo thomas@friendlyvillagers,

wir erlauben jedoch, dass jemand konkrete Fragen zu seinen (Haus-)Aufgaben stellt, solange die sich beantworten lassen, ohne den Lerneffekt der Aufgabe zu zerstören.

wenn ich eine Lösung der Aufgabe bekomme, die aus dem Internet stammt, ist sie ungültig.

Dabei solltest du unterscheiden, ob derjenige, der den Code gepostet hat, auch der ist, der ihn bei dir einreicht. In diesem Thread stammt aller Code vom Fragesteller. Wenn er diesen (nachweislich eigenen) Code später bei dir einreicht, sollte das ok sein. Problematisch ist nur, wenn sich jemand stillschweigend fremden Code zu eigen macht.

Wenn du pauschal sagen würdest, dass Code, der im Internet zu finden ist, nicht verwendet werden darf, nimmst du den Lernenden die Möglichkeit, im Netz Fragen zu ihrem selbst erstellten Code zu stellen.

Insofern ist auch der Satz ... irreführend.

Bezogen auf die eigentliche Aufgabe vielleicht. Aber der Satz bezog sich ja auf das, was der Thread-Ersteller gefragt hatte. Den Text deiner Aufgabe kannte ich zu diesem Zeitpunkt nicht. Bezogen auf deine Aufgabe kommt der Satz einfach nicht zum Tragen, weil in dem Moment, wo er relevant werden würde, die Suche laut Aufgabe sowieso abgebrochen wird.

herbivore

20.11.2014 - 22:59 Uhr

Hallo digi333,

es kommt auf die Reihenfolge [EDIT]=Z-Order[DIT] von Top und Fill an.

Siehe auch vordrängelnde Controls (Control.Dock).

herbivore

20.11.2014 - 22:50 Uhr

Hallo inflames2k,

ein Timer.Elapsed-Ereignis gibt es nur bei System.Timers.Timer. Bei System.Windows.Forms.Timer heißt das Event Tick. Und bei System.Threading.Timer gibt es gar kein Event, sondern dort übergibt man stattdessen einen Callback-Delegaten an den Konstruktor.

Hallo Centrii,

für Windows-Forms-Programme sollte man normalerweise System.Windows.Forms.Timer benutzen, wenn es darum geht, einen GUI-Zugriff durchzuführen, denn das Tick-Event läuft automatisch im GUI-Thread.

Was hast du denn im Debugger (siehe [Artikel] Debugger: Wie verwende ich den von Visual Studio?) bzw. mit entsprechenden Log-Ausgaben über die tatsächlichen Abläufe herausgefunden?

Bitte beachte auch, was meine Vorredner geraten/gefordert haben.

herbivore