Laden...
Avatar #avatar-3202.png
RattuS myCSharp.de - Member
Anwendungsentwickler Wiesbaden Dabei seit 23.08.2008 68 Beiträge
Benutzerbeschreibung

Forenbeiträge von RattuS Ingesamt 68 Beiträge

19.11.2010 - 21:28 Uhr

Ich hab das jetzt doch mit dem BGW gelöst. Es ist nicht nur einfacher, sondern scheinbar auch schneller.

19.11.2010 - 19:04 Uhr

Hallo,

ich rufe eine Methode via BeginInvoke auf, in der ich nach Abschluss/EndInvoke eine MessageBox aufrufe. Diese MessageBox ist bedingt durch den erzeugten Thread leider ohne Parent, folglich hängt die MessageBox ohne Fokus herum und wird mit einem Standard-Icon in der Taskbar angezeigt. Wie kann ich meinem Delegat ein Parent-Handle mitgeben bzw. wie kann ich von diesem Thread auf den aufrufenden GUI-Thread verweisen?

Ich hab das FAQ zu Control-Invoke gelesen, komme aber zu keiner Lösung, was wohl auch damit zusammenhängt, dass ich das ganze Invoke-Prinzip noch nicht ausreichend verstehe.

  
        private delegate void UpdateCheck(out string downloadLink);
        private UpdateCheck updateCheck;

  
        private void CheckForUpdate()
        {
            string x = string.Empty;
            updateCheck = new UpdateCheck(CheckForUpdateDelegate);
            AsyncCallback callback = new AsyncCallback(InformAboutUpdateDelegate);
            updateCheck.BeginInvoke(out x, callback, null);
        }


        private void CheckForUpdateDelegate(out string downloadLink)
        {
            // Zuweisung eines Wertes auf den out-Parameter
        }
        private void InformAboutUpdateDelegate(IAsyncResult result)
        {
            string resultLink = string.Empty;
            updateCheck.EndInvoke(out resultLink, result);

            // Auswertung des out-Parameters und Aufruf der MessageBox
        }

So wirklich richtig erscheint mir diese out-Parameter-Lösung auch noch nicht. 🤔
Oder nimmt man für solche Dinge lieber gleich einen BackgroundWorker?

Danke im voraus.

18.10.2010 - 10:19 Uhr

1-2 Pixelfehler sind bei handelsüblichen TFTs (Pixelfehlerklasse II) leider im Rahmen der Qualität, damit muss man leben.

trotzdem würde es mich interessehalber noch brennend interessieren, warum ein 1x1 form eine größe von 2x2 hat 😉

Weil das .NET es so will. Es zeichnet auf x/y und jeweils 1 Pixel nach rechts/unten.

Mit CreateWindow(Ex) hast du das Problem übrigens nicht.

17.10.2010 - 01:49 Uhr

Du könntest dir eine File-Copy der DB machen. Ansonsten gibt es in der C-Schnitstelle eine Methode sqlite3_open_v2(), die du mit SQLITE_OPEN_READONLY aufrufen kannst. Ob das dein Problem löst, weiß ich allerdings nicht.

17.10.2010 - 00:19 Uhr

Wie wäre es, wenn du uns einfach mal die 3 berühmten BackgroundWorker-Events zeigst? Kürze einfach die irrelevanten IO-Stellen der mp3s heraus.

16.10.2010 - 23:59 Uhr

Du machst das schon richtig mit Open und Close, siehe
>

Zu berücksichtigen ist, dass es sich bei SQLite um ein Flat-File-DBS handelt, das zwar Pooling seit Version 3(?) kennt, aber dies keinen Geschwindigkeitsvorteil bewirkt. Ich behaupte an dieser Stelle sogar, dass es die Zugriffsgeschwindigkeit bei sehr vielen Abfragen verlangsamt.

16.10.2010 - 23:46 Uhr

Und wenn du bei der Win32-API bleiben willst:
Prüfen, ob Fenster minimiert ist (IsIconic), dann ggf. ShowWindowAsync mit SW_RESTORE aufrufen.

15.10.2010 - 22:07 Uhr

SQLite ermöglicht wie die serverseitigen Datenbanksysteme parallelen Zugriff, Firefox sollte beim Zugriff also kein Problem für dich darstellen.

Was mir spontan zu dieser Methode einfällt:

  1. Du öffnest und schließt bei jeder Abfrage die Datenbankverbindung. Wenn du viele Abfragen machst, solltest du die Verbindung im Speicher behalten und als Parameter übergeben.
  2. Dein ResultSet besteht zwangsweise aus Strings, was ansich kein Problem ist, da du die Felder nachträglich parsen könntest. Du könntest die Dinger aber auch als object belassen.
  3. SQLiteDataReader erbt die IEnumerable-Schnittstelle afaik, also greif ruhig zur foreach-Schleife.
  4. SQLite schmeißt gerne Exceptions. Du solltest zumindest die SQLiteException behandeln.
15.10.2010 - 21:53 Uhr

X2540 -> Y821 -> T3

Diese drei Werte sollen als label in der GUI erscheinen. Hat jemand einen Denkanst0ß für mich? 😃

Wofür soll die Anzeige denn dienen?

12.09.2010 - 19:49 Uhr

GetWindowText

Du müsstest dir dann lediglich das Handle zur PID holen.

04.09.2010 - 19:48 Uhr
Screen.PrimaryScreen.WorkingArea
03.09.2010 - 23:42 Uhr

Ich habe einen erwähnenswerten Fehler in diesem Beispielprojekt gefunden: Du befüllst das ListView mit .Items.Add in der Schleife, anstatt die schnellere Items.AddRange-Methode zu verwenden. Das beschleunigt das Befüllen des ListView um mindestens 80-100%, also gut doppelt so schnell. Direkter Vergleich auf meiner Maschine (C2Q, 2,83 GHz): DGV ~30ms, LV ~120ms. "25-mal schneller" halte ich doch eher für unwahrscheinlich, denn selbst auf meiner älteren Testmaschine (P4, 3 GHz) erreiche ich diese Differenz nicht annähernd.


       private void FillListView() {
         Stopwatch SW = Stopwatch.StartNew();
         ListViewItem[] items = new ListViewItem[RowCount];
         for (int i = 0; i < RowCount ; i++) {
            ListViewItem lvi = new ListViewItem(i.ToString()); // this.ListView1.Items.Add(i.ToString());
            lvi.UseItemStyleForSubItems = false;
            lvi.ImageIndex = i % this.ImageList1.Images.Count;
            ListViewItem.ListViewSubItem lvsi = lvi.SubItems.Add(i.ToString());
            lvsi.BackColor = Color.Red;
            lvsi = lvi.SubItems.Add(i.ToString());
            lvsi.BackColor = Color.Blue;
            lvsi = lvi.SubItems.Add(i.ToString());
            lvsi.BackColor = Color.Violet;
            lvsi = lvi.SubItems.Add(i.ToString());
            lvsi = lvi.SubItems.Add(i.ToString());
            items[i] = lvi;
         }
         this.ListView1.BeginUpdate();
         this.ListView1.Items.Clear();
         this.ListView1.Items.AddRange(items);
         this.ListView1.EndUpdate();
         this.ToolStripStatusLabel1.Text = string.Format(
            "filled in {0} Milliseconds", SW.ElapsedMilliseconds);
       }

03.09.2010 - 23:22 Uhr

Das DGV ist zweifellos komfortabler und bietet grundsätzlich mehr Umfang. Dennoch vielleicht etwas Overkill für einfache Listen. 😃

03.09.2010 - 21:16 Uhr

Ich weiß ja nicht, wer das Programm am Ende bedienen soll, aber normalerweise entwickelt man eine Oberfläche nach den Regeln der "user experience" und dazu zählt das "Ausgrauen" von Schaltflächen, die nicht verwendbar sind.

Wie auch immer, folgende Ideen:*Den Draw-Event der Controls überschreiben und das "Ausgrauen" weglassen. *Die Events der Controls entsprechend validieren, sodass die Controls keine Reaktion zeigen. *Die Events der Controls gar nicht erst loslassen.

03.09.2010 - 21:07 Uhr

Das ListView-Steuerelement dürfte passen. Die "Details"-Ansicht ermöglicht eine Auflistung mit einem Icon pro Zeile und beliebig vielen Spalten, die mit einer kleinen Modifikation sogar sortierbar sind.

02.09.2010 - 17:35 Uhr

Übrigens hat Windows ein derartiges Tool bereits seit Generationen, Stichwort: charmap.

01.09.2010 - 15:43 Uhr

Ich habe mittlerweile SendMessage jetzt mal mit IntPtr für wParam und lParam überladen und siehe da: es funktioniert. Also wird die Adresse als IntPtr wohl nicht richtig umgewanelt. Problem ist jedenfalls gelöst. 😃

31.08.2010 - 20:54 Uhr

Hallo,

ich arbeite an einer kleinen Anwendung, die die Caption eines beliebigen Fensters manipulieren soll. Leider scheitere ich am Senden des Strings via SendMessage/WM_SETTEXT. Die Nachricht erreicht das Zielfenster zwar, aber das Ergebnis ist ein Leerstring.


        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(
              int hWnd,
              uint msg,
              long wParam,
              long lParam
              );

        private void RenameWindow(int hWnd, string text)
        {
            IntPtr textPointer = Marshal.StringToHGlobalAuto(text);
            SendMessage(hWnd, 0x0C, 0, (long)textPointer);
        }

Was bisher leider nichts gebracht hat:*anderes CharSet *[MarshalAs(UnmanagedType.LPStr)] string lParam im SendMessage *WM_COPYDATA, da es nicht alle Anwendungen verarbeiten

Die Adresse des gesendeten Strings stimmt. Der Inhalt der Adresse stimmt auch nach dem Absenden noch.

Hat noch jemand eine Idee? Danke im voraus.

11.01.2010 - 19:19 Uhr

Danke Florian, tatsächlich verursacht die ImageList das Problem. 😃

11.01.2010 - 17:55 Uhr

Klasse Kommentar. Hirn ausschalten und einfach mal arrogant drauf losmotzen.

Die IO/Access-Exceptions fange ich natürlich im Catch-Block ab, das sieht man bloß nicht, weil ich die Catches auf { } minimiert habe (der Codeausschnitt ist ohnehin schon so groß). Tu' mir einen Gefallen und drück das große X oben rechts, du bist mir schon mehrfach negativ aufgefallen. Deine Hilfe möchte ich nicht, ErfinderDesRades. Danke für dein Verständnis.

10.01.2010 - 18:03 Uhr

Stimmt, die ImageList habe ich vergessen auszulagern, aber das ist leider nicht das Problem.

Den GUI aktualisiere ich gar nicht permanent. Ganz im Gegenteil, der GUI bekommt erst am Ende des BGW die Daten in das Control (ListView) übermittelt.

Edit: Ich muss gerade feststellen, dass dieser Zeichenfehler auch ohne BGW vorkommt. Seltsam, könnte das etwas mit Vista zu tun haben?

10.01.2010 - 17:22 Uhr
        private void GetFiles(string directory, bool subDirectories)
        {
            if (working) return;

            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(GetFilesWorking);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(GetFilesWorkerCompleted);

            if (!worker.IsBusy)
            {
                SetProgress("Getting files of the selected directory...", true);

                imageListIcons.Images.Clear();
                worker.RunWorkerAsync(new object[] { directory, subDirectories });
            }
        }

        private void GetFilesWorking(object sender, DoWorkEventArgs e)
        {
            object[] arguments = (object[])e.Argument;
            string directory = (string)arguments[0];
            bool subDirectories = (bool)arguments[1];

            if (directory.Length <= 0) return;

            BackgroundWorker worker = sender as BackgroundWorker;
            List<ListViewItem> items = new List<ListViewItem>();

            try
            {
                string[] files = Directory.GetFiles(directory);
                foreach (string file in files)
                {
                    FileInfo info = new FileInfo(file);
                    imageListIcons.Images.Add(file, Program.GetIcon(file));

                    ListViewItem item = new ListViewItem(new string[] { Program.CutFileExtension(info.Name), String.Empty, info.Extension.Replace(".", String.Empty).ToUpper(), Program.CovertBytesToUnit(info.Length) }, file);
                    item.Tag = file;
                    items.Add(item);
                }
            }
            catch { }

            if (subDirectories)
            {
                try
                {
                    string[] folders = Directory.GetDirectories(directory);
                    foreach (string folder in folders)
                    {
                        GetSubFiles(folder, items);
                    }
                }
                catch { }
            }

            e.Result = items.ToArray();
        }

        private void GetFilesWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            listViewFiles.BeginUpdate();
            listViewFiles.Items.Clear();
            listViewFiles.Items.AddRange((ListViewItem[])e.Result);
            listViewFiles.EndUpdate();

            SetProgress("Ready", false);
        }

        private void GetSubFiles(string directory, List<ListViewItem> items)
        {
            try
            {
                string[] files = Directory.GetFiles(directory);
                foreach (string file in files)
                {
                    FileInfo info = new FileInfo(file);
                    imageListIcons.Images.Add(file, Program.GetIcon(file));

                    ListViewItem item = new ListViewItem(new string[] { Program.CutFileExtension(info.Name), String.Empty, info.Extension.Replace(".", String.Empty).ToUpper(), Program.CovertBytesToUnit(info.Length) }, file);
                    item.Tag = file;
                    items.Add(item);
                }
            }
            catch { }

            try
            {
                string[] folders = Directory.GetDirectories(directory);
                foreach (string folder in folders)
                {
                    GetSubFiles(folder, items);
                }
            }
            catch { }
        }
10.01.2010 - 15:33 Uhr

Hallo,

altes Spiel: Ich führe einen aufwendigen Prozess aus, möchte dabei aber den GUI weiterhin arbeiten lassen. Also nehme ich mir den BGW und lagere alles soweit aus. Trotzdem hab ich jetzt das Problem, dass der GUI sich nach Abschluss des BGW über den RunWorkerCompleted nicht korrekt neuzeichnet. Blockieren tut der GUI zunächst nicht, er zeichnet Controls beim Darüberbewegen mit der Maus sogar neu. Aber nach wenigen Sekunden blockiert dann alles, ironischerweise zeichnet sich sogar die Taskbar von Windows Vista falsch und überlappt. Beim Öffnen des Kontaktmenüs in der Taskleiste schmiert die Anwendung dann still und heimlich ab, keine Meldung, keine Ahnung. Debug hat nicht viel gebracht, denn die Events des BGW laufen alle sauber durch und beim Pausieren danach zeigt er nur auf Application.Run(...). Irgendwie hab ich das Gefühl, dass der BGW nicht vollständig verarbeitet wird. 😭

Mit freundlichen Grüßen,
pogo

PS: Es handelt sich bei dem "aufwendigen Prozess" eigentlich nur um das Auslesen eines gewählten Verzeichnisses samt Unterverzeichnisse. Und nein, DoEvents() wurde nicht benutzt. 😉

01.05.2009 - 18:30 Uhr

Mit Factory Method arbeite ich für gewöhnlich. Nur ist fraglich, ob sich Klassen für einzelne Objekte lohnen. Das Objekt bleibt so oder so die gesamte Laufzeit am Leben. Vorteilhaft wäre es also nur, wenn ich das Objekt für längere Zeiträume nicht benötige, um dann den Speicher dafür wieder freizugeben, wobei es sich bei der Anwendung ohnehin nicht um ein speicherkritisches Instrument handelt. ^^

01.05.2009 - 16:40 Uhr

Hallo,

folgendes Problem beschäftigt mich: Wenn man Objekte programmweit braucht (z.B. Zustandsvariablen oder Einstellungen - ohne sie permanent in den Konstrukturen zu übergeben), diese als Existenz aber nur einfach vorkommen können, wo sollte man diese dann anlegen?

Angenommen ich erstelle ein neues Windows-Forms-Projekt bei C# unter Visual Studio. Einsprungpunkt der Anwendung ist die statische Klasse "Program" mit der Methode "Main". Bietet sich diese statische Klasse "Program" bereits als Singleton an bzw. sind statische Klasse überhaupt mögliche Singletons? Eine andere Idee wäre eine öffentliche Klasse zu schreiben, die beim Einsprungpunkt einmalig instanziert wird (= Singleton?).

06.03.2009 - 09:31 Uhr

Mir fallen dazu 2 Möglichkeiten ein:
1.TransparencyKey:
Du setzt this.TransparencyKey auf die Farbe, die nicht gezeichnet, d.h. transparent, werden soll.

1.BackColor:
Du fügst Folgendes dem Konstruktor hinzu:

this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

Und setzt this.BackColor dann auf Color.Transparent.

04.03.2009 - 08:30 Uhr

Hallo JunkyXL. Dein Vorschlag löst mein Problem leider nicht.
*OnPaintBackground mit Transparent zeichnen bewirkt, dass die komplette Windows.Form Transparenz annimmt (siehe Screenshot). *.BackColor auf Transparent setzen lässt das Problem offen, dass darunterliegende Controls nicht gezeichnet werden.


(Panel mit 3 Controls)

Die Transparenzdarstellung müsste irgendwie die Z-Reihenfolge einbeziehen.

03.03.2009 - 23:57 Uhr

Hallo,

ich habe hier eine Klasse, die von Control erbt. Im Paint-Event, den ich überschreibe, zeichne ich eine Ellipse und fülle diese mit einer Farbe. Leider zeichnet sich das Control permanent rechteckig mit .BackColor, sodass die Ellipse am Außenrand stets eckig bleibt. Ziel ist es, dass die Ellipse am Außenrand transparent ist - und zwar durchgängig, sodass ich mehrere Controls übereinanderlegen kann. Mit .SetStyle kann man Transparenz ermöglichen, leider wirkt diese Transparenz nur auf den überliegenden Container (Container.Controls).

Wie kann ich mein Problem lösen? 😮

11.02.2009 - 16:15 Uhr

Leite dir doch einfach deine Steuerelemente ab und überschreib die Standardfarben (wenn es denn das ist, was du möchtest).

z.B.

    public class MyButton : Button
    {
        public override Color BackColor
        {
            get
            {
                return Color.Blue;
            }
        }
    }
30.11.2008 - 20:33 Uhr

schau dir mal das an:

ergänzungsfenster.Show(hauptfenster);  

Prima, funktioniert. Ich war irgendwie davon ausgegangen, dass .Show() das Fenster automatisch dem aufrufenden Fenster als Parent zuordnet. ^^

30.11.2008 - 17:26 Uhr

Hallo,

ein recht simples Problem: Ich habe 2 Fenster, nennen wir sie Hauptfenster und Ergänzungsfenster. Jetzt möchte ich, dass beim Aufrufen des Hauptfensters (z.B. über Taskleistenauswahl oder Wiederherstellen) das Ergänzungsfenster ebenfalls aufgerufen wird bzw. ebenfalls auf die oberste Z-Ebene kommt, aber keinen Fokus erhalten soll.

Selektives TopMost auf das Ergänzungsfenster beim Hauptfensterfokus funktioniert nur, solange keine Dialoge über das Hauptfenster eintreten, da sonst die Dialoge keinen Eingangsfokus haben. Gibt es vielleicht einen alternativen Event, den man abfangen kann, um dieses Vorhaben zu lösen?

30.11.2008 - 13:47 Uhr

Ich lasse mich aber gerne vom Gegenteil überzeugen,
das glaube ich nach deinen, in meinen Augen eher an der Sache vorbeigehenden Einwänden langsam nicht mehr.

Hallo herbivore, zitier mich doch bitte vollständig, wenn du schon auf eine Aussage zurückgreifst.

Ich lasse mich aber gerne vom Gegenteil überzeugen, aber dann bitte mit einem ausführlichen Argument.

Die bisher genannten Argumente, auch wenn es deiner Meinung nach die Summe dieser ausmacht, sind in meinen Augen allesamt nur sehr schwach. Das der Entwickler fehlerhaft programmieren kann, hat nichts mit den technischen Mitteln zu tun, die ihm angeboten werden. Obsolete Methoden wurden im .NET doch sowieso weitestgehend minimiert.

30.11.2008 - 12:30 Uhr

mit doevents lässt sich auf einfache aber äußerst unübersichltiche art und weise eine stackoverflow-exception provozieren, die meist nur auf schwächeren maschinen (also meist beim kunden) auftritt.

Kunde mit leistungsschwachen Rechnern und .NET-Software passt nicht gut zusammen. Hier wurde schon vor der eigentlichen Entwicklung ein fataler Fehler begangen.

29.11.2008 - 22:17 Uhr

Damit DoEvents seinen Zweck erfüllt, muss ja in einer Schleife immer wieder aufgerufen werden.

Nicht zwangsweise. Es gibt viele Szenarien, wenn auch nicht gerade bei den WinForms, bei denen die Messages während eines nicht in einer Schleife beindlichen Ablaufes verarbeitet werden sollten.

29.11.2008 - 21:48 Uhr

DataGridView.SelectedRows ist doch lediglich ein Datenarray, das bei einer Selektion entsprechend gefüllt wird. Die .Count-Methode gibt einfach nur den Zählerwert des letzten Offsets im Array zurück. DataGridView.SelectedRows.Count ist also garantiert nicht langsam. 😉

29.11.2008 - 21:43 Uhr

Außer redundanter Verarbeitung bei schlechtem Messaging, kann ich dem Application.DoEvents nichts "Unsauberes" abgewinnen?

29.11.2008 - 21:39 Uhr

Dein Problem ist mir irgendwie nicht ganz klar geworden. Suchst du generell nach einer Methodik?

Ich möchte dabei das vergleichen mit gespeicherten wörtern vermeiden!

Warum? Der Prozessor arbeitet beim Stringvergleich mit MOVS und ESI/EDI sehr effizient und schnell. Das .NET ist keinesfalls langsam bei der allgemeinen Stringverarbeitung.

29.11.2008 - 21:26 Uhr

Ich denke nicht, dass es prinzipiell "unsauber" ist (mal unabhängig von der Verwendung bei diesem Problem hier), mit Application.DoEvents zu arbeiten, schließlich sind wir hier nicht bei VB6. Ich lasse mich aber gerne vom Gegenteil überzeugen, aber dann bitte mit einem ausführlichen Argument. 🙂

21.11.2008 - 16:52 Uhr

SAP ist ja auch an allen Ecken und Kanten modifizierbar. Aber prinzipiell wird dieser Tree geboten. 😉

20.11.2008 - 23:19 Uhr

Dieses TreeView-Struktur-System ist doch ganz ordentlich. Man hat seine übergeordneten Punkte, kann bei Bedarf eine Menge aufklappen oder eben nach einer Funktionalität suchen. Für den Schnellzugriff kannst du häufig verwendete Aktionen listen und Indizes einrichten. Bei SAP ist diese Umsetzung integriert, allerdings nicht grafisch ausgeschmückt, sondern plain. Aber das bekommst du mit Sicherheit hin. 🙂

20.11.2008 - 23:11 Uhr

Den TabIndex kannst du dir sparen bzw. solltest du den dann auf i setzen (zum Durchschalten der DGV). Die schönere Schreibweise für x = x + y wäre übrigens x += y. 🙂

Prinzipiell dürften die DGV kein Problem sein. Ob nun 4 DGV oder 4 DataSets, die Speicherbelegung ist so oder so ähnlich viel und das Zeichnen des Grids kostet bei dieser Menge mit Sicherheit keine merkenswerte Performance.

16.11.2008 - 23:42 Uhr
Form2 frm2 = new Form2(); 
frm2 .Show();
this.Focus();

Schöner geht es mit SetWindowPos. Google hilft dir sicherlich weiter.

15.11.2008 - 15:08 Uhr

Wir reden aneinander vorbei. Wenn ich Lokalisierung sage, meine ich die von VS angebotene Lokalisierung, die im Designer eine editierbare Mehrfachansicht von Forms erlaubt. Anschließend werden diese Mehrfachansichten seperat ausgelagert und beim Zielsystem, abhängig von der Spracheinstellung, entsprechend eingelesen (das Dateiformat spielt hier überhaupt keine Rolle). Diese Art der Lokalisierung erfordert entweder eine Übersetzung in der Entwicklungsumgebung oder Drittanwendungen, wenn man sich auf die VS-Variante verlässt. Die andere Variante wäre, eine eigene Funktionalität zu schreiben. Das Schema bleibt dennoch das gleiche: Informationen auslagern und beim Zielsystem wieder abrufen. Ob das durch die von MS vorgegebene Schematisierung oder einer eigenen Funktionalität durchgeführt wird, bleibt jedem Entwickler wohl selbst überlassen.

15.11.2008 - 13:03 Uhr

Mit OnPaint sollte das ganz gut funktionieren. Du benötigst dann lediglich eine Kollisionsprüfung für deine Panel-Controls.

15.11.2008 - 12:59 Uhr

Z.B. bekommen unsere Übersetzer ein Excel-Sheet mit allen englischen Begriffen (wird durch ein Tool erzeugt, welches ich geschrieben habe). Diese wird anschließend wieder eingelesen und daraus die Satelliten-Assemblies kompiliert (ebenfalls durch das Tool). Neue Sprache fertig.

Und wo ist da der Unterschied zu herkömmlichen Sprachdateien in XML/TXT/XLS/HTML w/e? Ich dachte, dass der größte Vorteil der Lokalisierung die designerunabhängige Beschreibung von Controls ist - ist das dann noch gegeben?

Wenn ich mir bei meinem Projekt vorstelle, dass ich jedes Formular, jeden Tab, jedes Element zum Umbenennen erst anklicken müsste, wäre das für mich unnötiger Zeitaufwand. Mit einer Sprachdatei weise ich alles lediglich einmal zu und muss für andere Sprachen später nur noch Zeile für Zeile in der Sprachdatei übersetzen. Ich habe dann zwar nach wie vor das Problem mit der Größe der Controls, aber wenn ich das Programmdesign von Anfang an nicht zu statisch aufbaue, stellt das kein ernsthaftes Problem dar.

schon mal was von catalyst gehört? (nicht den von ATI)

Willst du mir damit sagen, dass dein Lösungsvorschlag nur Sinn macht, wenn man sich eine 4000 € teure Lizenz kauft? Failed.

14.11.2008 - 18:53 Uhr

settings sind nciht dazu da mehrsprachigkeit zu unterstützen, sondern anwendungseinstellungen (also nur internas) zu hinterlegen und veränderbar zu machen.

Denk mal scharf nach, in welchem Format diese Settings gespeichert werden. Außerdem: Settings bedeutet doch nicht gleich, dass es nur programminterne Präferenzen umschließt. Resource-Dateien können beliebige Informationen speichern.

mein argument ist, das ich weiß, das du unrecht hast. schau dir an, wie z.b. das framework solche sachen löst.

Die Potion Arroganz kannst du gerne behalten. Lokalisierung hat seine Nachteile, keine entwicklerfreie Editierbarkeit, Übersetzung nur im Designer, hoher Zeitfaktor bei Projekten mit 1000+ Controls mit extremen Aufwand bei steigender Sprachenanzahl.

14.11.2008 - 13:01 Uhr

du solltest dir die lokalisierungsgeschichte nochmals gründlich ansehen, denn deine behauptung hat keinen halt.

Und anstatt mir vorzuschlagen, was ich zu tun habe, solltest du lieber ein Gegenargument bringen.

Text, den ich bei Dialogen etc. mehrsprachig anzeigen möchte, muss ich trotzdem in den Settings speichern (mal unabhängig davon, ob das mit Properties oder seperaten Resources gelöst wird). Fakt ist, dass das Arbeit ist, die man nicht abgenommen bekommt. IMO ist es schneller eine Textdatei (mit einem externen Editor) zu schreiben, als einen Designer zu verwenden.

13.11.2008 - 19:31 Uhr

Lokalisierung hin oder her: Text, der nicht auf Controls klebt, bleibt trotzdem offen. Das dann alles per Properties.Settings einzuarbeiten, ist mühselig.

Vielmehr solltest du dir ein kleines Modul schreiben, dass Sprachdateien ausliest und das Programm entsprechend anpasst. Das geht ganz simpel über eine TXT/INI- oder gar XML-Datei, die du Zeile für Zeile (bzw. Tag für Tag) einliest und z.B. mit Hilfe einer SortedList (die Keys wären dann die Controls) abrufst.

Edit: Notepad++ (Open Source) arbeitet ebenfalls mit XML-Sprachdateien. Bei Bedarf kannst du dir den Code dort ja mal anschauen.

09.11.2008 - 13:51 Uhr

Okay, danke ihr beiden. Es ist also sinnvoller auf FTP-Ebene entsprechende Einschränkungen einzurichten.

08.11.2008 - 16:23 Uhr

Hallo zusammen,

in einem Programm möchte ich eine Datei per FTP hochladen. Dazu hatte ich bis heute noch Network.UploadFile verwendet (VB .NET). Mir ist allerdings aufgefallen, dass die FTP-Zugriffsdaten (Benutzer, Passwort) dadurch ziemlich unsicher abgelegt sind. Anweder mit bösen Absichten (und entsprechenden Kenntnissen) könnten diese Daten theoretisch auslesen. Na ja, theoretisch könnten sie dann auch die Startadresse des Streams, der hochgeladen werden soll, ändern. Bin ich nur zu paranoid oder gibt es eine bessere Methode? Wie siehts mit WebClient.UploadFile aus? Sicherer oder identische Funktionalität?

Mit freundlichen Grüßen
pogo