Laden...

Forenbeiträge von SeeQuark Ingesamt 946 Beiträge

21.09.2009 - 16:38 Uhr

Ansonsten, wenn die Platzhalter mehrmals auftauchen einfach "String aus dem Language File".Relplace("<Platzhalter>", "ausgetauschter Platzhalter) verwenden.
Bei mehreren Replaces in einem string sollte man aber auf einen StringBuilder umsteigen.

Aber zum Lokalisieren würde ich anders vorgehen...

mfg
SeeQuark

14.09.2009 - 22:44 Uhr

Entweder kannst du das ganz simpel über eine Mausklicksimulation auf einem bestimmten Punkt lösen, oder aber du informierst dich über das UI Automation Framework.
Ein paar Links:*MSDN: Übersicht über die Benutzeroberflächenautomatisierung *CodeProject: UI Automation Framework using WPF *Forumssuche *Google 😉

mfg
SeeQuark

14.09.2009 - 12:33 Uhr

Probiere mal die Methoden Canvas.GetLeft und Canvas.GetTop aus.

mfg
SeeQuark

14.09.2009 - 12:20 Uhr

Du bist in einem WinForms Forum. Aber fragst du etwas über WPF?

Wenn ja: Das Problem könnte die Priorität von Abhängigkeitseigenschaftenwerten sein:1.CoerceValueCallback 1.Animationen 1.Lokale Werte 1.Style Trigger 1.Template Trigger 1.Style Setter 1....

Der Trigger hat weniger Gewicht wie ein direktes Setzen der Property.
Irgendwo muss der Wert in einer höheren Priorität gesetzt worden sein.

mfg
SeeQuark

14.09.2009 - 11:27 Uhr

du darfst nur keine Teile von Windows Forms [...] verwenden

Sicher darf man Windows Forms verwenden. Die Anwendung von BerndFfm sieht mir stark nach WinForms aus (Buttons).
Was man nicht verwenden darf ist WPF. Speziell für Linux gibt es auch noch Gtk# im Framework.

mfg
SeeQuark

10.09.2009 - 21:54 Uhr

Ausser .7zip gibts auch noch .7z.
Die über Google gefundene Seite kennt .7zip nicht einmal. Dafür .000 und 165 andere: http://www.fileinfo.com/filetypes/compressed.

Allerdings kann man ohne Probleme ein schwach komprimiertes zip-File weiter komprimieren. Bei den anderen Endungen ist es eigentlich das Selbe.
Andere Dateitypen kommen natürlich nicht vor, wie beispielsweise .docx, was ja auch ein .zip-File ist.

Jeder gute Dateityp sollte ja nicht mehr stark komprimierbar sein, darum finde ich deine Idee etwas komisch.

mfg
SeeQuark

10.09.2009 - 21:17 Uhr

mein einzigstes Problem

Nur so kann man das natürlich nicht beurteilen. Du hast den Code und den Debugger.
Beispielsweise kannst du in der Schleife testweise Thread.Sleep(500); einbauen und schauen, ob die CPU Belastung immer noch so hoch ist.
Wenn ja, dann liegt das Problem woanders.

Auch kannst du den Rythmus von 3 Sekunden (was aber aus meiner Sicht kein Problem darstellen sollte) etwas hochsetzen und schauen was passiert.

Vielleicht verschleuderst du auch einfach die Resourcen: Dispose implementieren und verwenden (IDisposable).
Also: Immer den gleichen Stream verwenden (am einfachsten StreamWriter, der kann schon strings) und am Ende disposen.
Müsste aber keinen grossen Performanzunterschied machen, sondern eher RAM-Probleme.

Wie man generell Tcp-Anwendungen macht, steht ja in meinem Link oben.

mfg
SeeQuark

10.09.2009 - 20:47 Uhr

Praktisch alles dazu steht dadrin: [FAQ] Kommunikation von 2 Forms.

Zu deinem Tcp-Problem: Ich habe den Code jetzt nicht angeschaut, aber vielleicht hilft dir eine Beispielsanwendung, die über Tcp fungiert: VersuchsChat.
So überträgt man allerdings normalerweise die Daten zwischen 2 Prozessen, oder zwischen 2 Computern.

mfg
SeeQuark

10.09.2009 - 20:39 Uhr

Mit den Leerzeichen geht das sicher am Einfachsten. Die Länge des Textes in Pixeln kannst du ja mit MeasureString und Alternativen bestimmen.
Wie du die Schriftart der Titelleiste ausliest, ist eine andere Sache...

Eine andere Lösung wäre, indem du das Zeichnen der Titelleiste selber beeinflusst. Das wäre ein Fall von [Artikel] Custom Window Border für Form's, zwar komplizierter aber etwas schicker (man kann es auf den Pixel genau machen).

mfg
SeeQuark

10.09.2009 - 20:22 Uhr

Das Hauptproblem scheint zu sein, wie du die E-Mail Adresse auslesen kannst.
So wie du denkst geht das beispielsweise mit folgendem Pattern:

(?<=\w+ *= *)[\d\.]+

Normalerweise liest man aber in den Matches die Groups aus.
Wie das geht steht im [Artikel] Regex-Tutorial

In Nützliche Regex-Pattern findet sich ein vordefiniertes Pattern für eine IP-Adresse.

\w+ *= *\b(?<IPAddress>(2([0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})(\.(2([0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})){3})\b

Das wäre dann das Pattern.

mfg
SeeQuark

09.09.2009 - 22:41 Uhr

So bindet mal eine DLL ein:

So macht man P/Invoke, bindet also eine unmanaged dll ein 😉
Ausserdem muss der Pfad schon bekannt sein.

Ich dachte da eher an Assembly.Load(path).

mfg
SeeQuark

09.09.2009 - 22:34 Uhr

Wenn ich dich richtig verstanden habe nach Plugin?
[QUOTE3=: [FAQ] Eigene Anwendung pluginfähig machen,http://www.mycsharp.de/wbb2/thread.php?threadid=34472]Denkbar wäre eine einfache, eigene Lösung bei der mit Hilfe von Reflection alle DLL Dateien aus einem Plugin-Verzeichnis geladen werden und nach Klassen gesucht wird, die eine bestimmte Schnittstelle implementieren.[/quote3]
Dazu siehe wiederum [Artikel] Reflection und Metaprogrammierung.

Mit WPF direkt hat das ja nichts zu tun.
Habe ich das richtig verstanden?

mfg
SeeQuark

09.09.2009 - 21:26 Uhr

Bin zwar nach ErfinderDesRades, aber trotzdem...

Über Reflection geht das ganz sicher. Mit Reflection kann man nicht nur auslesen, sondern auch verändern (Variablen, aber sogar auch Code).

Trotzdem ist es eindeutig nicht besonders ideal dafür Reflection zu verwenden.
Am Einfachsten wäre:

public class Example
{
   // ... dein Code

   public static IEnumerable<Example> GetEnumerable()
   {
      yield return Ex1;
      yield return Ex2;
      yield return Ex3;
      yield return Ex4;
   }
}

foreach geht dann mit Example.GetEnumerable().

Alles als eigene Property zu definieren finde ich allerdings nicht besonders gut.
Vor allem wenn es so ein gewisses Schema hat, sparst du dir Arbeit, wenn du es per Methode bereitstellst: static GetExample(int index) { /* ... */ }.
Ein Array geht zwar auch, aber dann hast du immer die gleiche Referenz, also wenn du eine Instanz veränderst, wird die Standard-Instanz auch mitverändert.

Dann ist auch der Code in GetEnumerable übersichtlicher.

Ohne diese Methode, also nur über einen statischen Typen ist foreach nicht möglich.

mfg
SeeQuark

09.09.2009 - 14:32 Uhr

Implizit steht das schon im Post über mir; es geht nicht.

Schlüsselwort dynamic: Methoden werden intern über MethodInfo ausgelesen und aufgerufen

Etwas anderes fällt mir nicht ein, und gibt es IMHO auch nicht. Zu Reflection: [Artikel] Reflection und Metaprogrammierung.

mfg
SeeQuark

09.09.2009 - 13:57 Uhr

Also ich habe das gestestet - und es geht nicht.

Etwas wie

List<object> list = new List<string>(new[] { "Hello", "World" });

ist nicht möglich. Und zwar aus gutem Grund; bei der List<object> könntest du ohne weiteres einen int hinzufügen. Und so einen Fehler zur Laufzeit zu kriegen ist nicht schön.
Implizit verwandeln kann man nur ein IEnumerable<_out_ T&gt;; List<T> bleibt List<T> und IList<T> entsprechend auch.

Trotzdem geht es: Mit dem Schlüsselwort dynamic.

Ein bisschen Code:

static void TestGenericActivator(Type type, params object[] addItems)
{
    // Schlüsselwort dynamic: Methoden werden intern über MethodInfo ausgelesen und aufgerufen -> geht bei passenden addItems
    Console.WriteLine();
    Console.WriteLine("Dynamic List");

    dynamic dynamicList = Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
    foreach (var item in (dynamic[])addItems)
        dynamicList.Add(item);
    foreach (var item in dynamicList)
        Console.WriteLine(item);

    // Cast: eine List<T> (wobei T nicht direkt object) kann man nicht zu einer List<object> casten; normale InvalidCastException
    Console.WriteLine();
    Console.WriteLine("Casted List");

    List<object> castedList = (List<object>)(Activator.CreateInstance(typeof(List<>).MakeGenericType(type)));
    // Hier (Laufzeit-)Exception: System.InvalidCastException was unhandled
    // "Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Collections.Generic.List`1[System.Object]'."
    
    foreach (var item in addItems)
        castedList.Add(addItems);
    foreach (var item in castedList)
        Console.WriteLine(item);
}

Aufrufe:

TestGenericActivator(typeof(object), 'U', 2);           // Problemlos
TestGenericActivator(typeof(string), "Hello", "World"); // Exception bei Cast
TestGenericActivator(typeof(float), 3, 1, 4, 1);        // Exception bei Cast (alles ints)
TestGenericActivator(typeof(int), "Exception!!!");      // Exception bei beiden Varianten:
// Microsoft.CSharp.RuntimeBinder.RuntimeBinderException was unhandled
// "The best overloaded method match for 'System.Collections.Generic.List<int>.Add(int)'
// has some invalid arguments"

Also: Mit Kovarianz geht auch nicht alles. Nur das, was idiotensicher ist (zu sein scheint).

mfg
SeeQuark

08.09.2009 - 22:38 Uhr

Erst einmal folgendes: [Hinweis] Wie poste ich richtig? 4, insbesondere 4c. Wälzt nicht eure Aufgaben auf uns ab.

Dennoch ein kleiner Tipp: Du musst jeder Person einen/bzw. mehrere Zahlenwerte zuordnen. Wenn Status=1, dann nur einen, wenn der Status=2, dann halt 2 Zahlenwerte, bei 3, 3, etc.

Was ich an der Aufgabenstellung nicht verstehe ist, dass es am Schluss immer die gleiche Person wird, die abgefragt wird. Sinvoller erscheint mir, dass wenn die Frage richtig beantwortet wurde der Status decrementiert wird.

EDIT: Mir wurde wirklich keine Warnung angezeigt, aber meine Lösung deckt sich so ziemlich mit der von michlG, nur anders formuliert.

mfg
SeeQuark

08.09.2009 - 21:53 Uhr

sollten Konstanten nich performance-Vorteile bieten? Minimale klar, aber Vorteile?

Minimale sicher, das ist ja eigentlich klar.
Der Unterschied der: Konstanten werden in den eigentlichen Code mit einkompilliert wie wenn du den Wert ganz normal als Literal geschrieben hättest.
Es wird also nicht zur Laufzeit der Wert gelesen (abgerufen), sondern schon zur Kompillierzeit.
Die Konstante ist auch in anderen Assemblies im IL-Code "hardcoded" und kann zu Problemen führen, wenn du die Konstante plötzlich änderst. Das merkt sie erst, wenn man sie neu kompilliert.
Bei Readonly-Felder passiert das nicht.

Die Geschwindigkeitsvorteile einer Konstante gegenüber einem readonly Field und sogar gegenüber einer Property sind allerdings kaum merklich.
Von dieser Seite sollte das eigentlich egal sein.

mfg
SeeQuark

08.09.2009 - 19:29 Uhr

Schau dir mal diesen CodeProject Artikel an: Create Icons for Folders in Windows Explorer, Using C#.

mfg
SeeQuark

08.09.2009 - 15:44 Uhr

Das geht natürlich auch, solange die Eingaben gleich bleiben.
Das Problem sind dann zum Beispiel :::{style="color: darkred;"}&quot;1.2.3&quot;){darkred}, :::{style="color: darkred;"}&quot;123&quot;){darkred}, :::{style="color: darkred;"}&quot;hello.world&quot;){darkred} oder einfach nur :::{style="color: darkred;"}&quot;.&quot;){darkred}. Bei manchen tritt sogar eine Exception auf.
Insgesamt, also wenn man solche Sachen berücksichtigt, braucht man so etwas mehr Code, ist aber etwas schneller.

mfg
SeeQuark

07.09.2009 - 22:07 Uhr

Um diese Formatbezeichner zu verwenden, muss es halt eine Zahl sein, und die Text-Property bei einem Label riecht so nach string.

Das einfachste wäre, sie zu parsen:

 decimal number;
if (decimal.TryParse(textSchlittenweg.Text, out number))
   MessageBox.Show(String.Format("{0:F1}", number); // oder was du auch willlst

anstatt decimal kannst du auch double oder float verwenden, hauptsache ist, dass das Objekt mit dem Formatbezeichner "0.0" oder "F1" umgehen kann, was bei einem string nicht der fall ist.

mfg
SeeQuark

02.09.2009 - 19:27 Uhr

Bei Activator.CreateInstance<T>() (was zwar im Prinzip gleich, aber schicker ist als (T)Activator.CreateInstance(typeof(T))), wird aber eine Exception geworfen, wenn der Typ keinen parameterlosen Konstruktor besitzt.
Daher fände ich


public T Resolve<T>() where T: new() {
    return new T();
}

besser.
Hier wird bei Compile time ein Error produziert.
Allerdings lohnt sich die Methode gar nicht mehr.

mfg
SeeQuark

02.09.2009 - 18:21 Uhr

Ich mach das immer so:

<Button ... IsDefault="{Binding IsFocused, ElementName=textBox}"/>

Bei einem Enter wird also schön der Button gedrückt, den du sowieso noch zur Kennzeichnung haben solltest.
Alternativ kannst du IsDefault direkt auf :::{style="color: darkred;"}&quot;True&quot;){darkred} setzen.

(Btw.: http://if-schleife.de){gray}

mfg
SeeQuark

01.09.2009 - 18:31 Uhr

So wie ich das überflogen habe, wird das schon berechnet (mit EstimateBestShearXFactor bzw. EstimateBestShearXFactor, Kommentar am Anfang der Methode lautet: :::{style="color: green;"}X Scherung bestimmen){green}).

mfg
SeeQuark

01.09.2009 - 17:31 Uhr

Vielleicht hilft dir auch noch dieser Thread: Problem mit xaml-Dateien unter VS 2008 SP1.

mfg
SeeQuark

01.09.2009 - 17:21 Uhr

Noch eine schöne Lösung hier im Forum: Verdrehten Text in Bitmap zurückdrehen

mfg
SeeQuark

31.08.2009 - 16:32 Uhr

Ich kann auch nicht casten:

InitializeImageComboX((List<IImageComboItem>)TaskStates.GetInstance().States);  

Und ein IEnumerable<T> ist halt keine List<T> 😉
Da ConvertAll<T> imho die einzige Methode ist, die eine List<T> zurückgibt wird es wohl die einzige Möglichkeit bleiben, solange der Parameter eine List<T> bleibt.
Aber das Problem an sich ist ja momentan ausreichend gut gelöst, so dass man es damit eigentlich beruhen lassen kann.

vielleicht ist das Problem, dass mein States kein Cast anbietet?

Cast ist eine Erweiterungsmethode. Mit using System.Linq; müsste sie eigentlich angeboten werden.
Aber du hast dann halt immer noch keine List<T>.

mfg
SeeQuark

31.08.2009 - 15:33 Uhr

Imho müsste ein ShowDialog reichen.
Andererseits ist das eine ziemlich schlechte Lösung, da alle Controls (und dazu gehören auch Forms) nur in einem einzigen Thread existieren sollten.

Siehe auch [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke)

mfg
SeeQuark

31.08.2009 - 15:25 Uhr

Das Konstrukt ist ein Lambda Ausdruck.
Falls es dich interessiert: [Artikel] Delegaten, anonyme Methoden, Lambda-Ausdrücke & Co.

Eigentlich ist es nicht einmal nötig. Mit .NET 3.5 geht auch

InitializeImageComboX(TaskStates.GetInstance().States.Cast<IImageComboItem>());

So ist es fast noch schöner...

mfg
SeeQuark

31.08.2009 - 15:11 Uhr

Hat jemand eine Idee?

.NET 4 verwenden 😁 Da geht das ohne Probleme und auch noch performant.

Aktuell musst musst du trotzdem casten. So etwas wie

InitializeImageComboX(TaskStates.GetInstance().States.ConvertAll<IImageComboItem>(p => p));

müsste gehen.

mfg
SeeQuark

25.08.2009 - 22:11 Uhr

Als abstract kann ich die Methode nicht deklarieren, da sie einen Body hat

Mach eine zweite Methode, die abstract ist.

abstract class BaseClass
{
   public void Method()
   {
      Thread.Sleep(10); // Notwendiger Body
      AbstractMethod(); // Abstrakte Methode aufrufen
   }
    
   protected abstract void AbstractMethod();
}

class SubClass : BaseClass
{    
   protected override void AbstractMethod()
   {
      Console.Beep();
   }
}

da sie einen Body hat und auch braucht.

Über diese Variante lässt sich der Body auch nicht "aus Versehen" löschen.

mfg
SeeQuark

25.08.2009 - 17:51 Uhr

Ich vermute auch mal, dass eine Regex hier kaum möglich ist.

Mein Versuch:

^(?<Command>([^:]+)): (?<Values>("[^"]+"|\([^\)]+\)|[^,]+),\s*)+$

Erstaunlicherweise braucht das Regex-Lab von herbivore mehrere Minuten (2 Regexlabs sind seit über 5 min daran) zur Berechnung wenn man dein unterstes Beispiel reinkopiert.
Aber mein Pattern passt sowieso nur, wenn am Schluss noch ein Komma folgt. Das könnte man durch kopieren der "Values"-Gruppe noch verhindern, aber ich finde lieber dem Response-String durch ein einfaches +"," noch ein Komma anhängen.

An die Grenzen stösst man hier, wenn es verschachtelt sein sollte, was unter Regex nicht geht. Also beispielsweise wenn du eine Gruppe auch noch unterteilen möchtest (solange diese Teilung nich auch wieder aus Gruppen bestehen kann geht das sogar).

Die Performanz von Regex ist eindeutig schlechter wie eine Split-Variante.

mfg
SeeQuark

22.08.2009 - 16:42 Uhr

Für Application.StartupPath braucht man eine Referenz auf die System.Windows.Forms.dll.
Andere Varianten (auch solche für Consolenanwendungen) finden sich da: [FAQ] Pfad zur eigenen Anwendung (EXE) ermitteln.

mfg
SeeQuark

22.08.2009 - 14:33 Uhr

Mit Lambda-Ausdrücken kannst du das eleganter schreiben:

string searchedKey = Array.Find(myKVP, p => p.Value == searchValue).Key;

Wobei ich nicht weiss, warum du ein Array aus KeyValuePairs brauchst.
Dazu wäre ein Dictionary imho besser geeignet.

mfg
SeeQuark

21.08.2009 - 22:38 Uhr

Vor kurzem habe ich mir das Buch Managed DirectX und C# gekauft.

Ich gebe mal den Hinweis, dass Managed DirectX schon seit längerem nicht mehr weiterentwickelt wird.
Schlimm ist das nicht, denn dir müsste mit dem Wissen über MDX ein Umstieg auf das normale DirectX oder SlimDX (der inoffizielle Nachfolger von DirectX) leichterfallen.
Andererseits hat MDX auch eigene Workarounds, ist also nicht nur ein reiner Wrapper.
Hier im Forum gibt es auch etwas über ManagedDirectX: [Artikel] Managed Direct3D Tutorial

Fehler CS1014: get- oder set-Accessor erwartet.
Die Fehler sind mir somit zwar klar da ja recht ausführliche Meldung vom Compiler, aber wie ich die Löse ist mir weitgehend unbekannt.

[Hinweis] Syntaxfehler selbst lösen (Compilerfehlermeldungen)

mfg
SeeQuark

20.08.2009 - 15:12 Uhr

Hosten kann man Win32 natürlich schon (WinForms ist ja im Prinzip auch nichts anderes).

Als eigenes Vektorgrafik-Objekt, das man auch skalieren und damit interagieren kann.

Das geht aber meines Wissens nach nicht.

Dieser Artikel über den "Airspace" könnte noch interessant sein: WPF-Interoperation: "Airspace" und Übersicht über Fensterbereiche

mfg
SeeQuark

19.08.2009 - 21:51 Uhr

Sowas?

class Base
{
    protected object Property
    {
        get
        {
            MethodBase calledMethod = new StackTrace().GetFrame(1).GetMethod();
            Console.WriteLine(calledMethod.IsDefined(typeof(TestAttribute), true));
            return new object();
        }
    }
}
class Sub : Base
{
    [Test]
    public void Method()
    {
        Object obj = base.Property;
    }
}

Theoretisch geht es so, mir kommt es aber nicht sehr optimal vor.
Wofür brauchst du es denn?

mfg
SeeQuark

19.08.2009 - 21:36 Uhr

Nein, das geht nicht. Wenn Console nicht static wäre, könntest du das zwar machen, aber mit statischen Klassen hast du keine Chance.

Siehe auch [gelöst] Warum sind die Klassen im Framework nicht partial?.

mfg
SeeQuark

16.08.2009 - 11:16 Uhr
// An die PropertyInfo kommen
PropertyInfo property = GetType().GetProperty("Test", typeof(string));

// Über Attribute.IsDefined auslesen
if (property.IsDefined(typeof(EinAttribut), true)))
   Console.WriteLine("Test hat das Attribute");

Generell also: MethodInfo.IsDefined oder Attribute.IsDefined.

mfg
SeeQuark

12.08.2009 - 20:31 Uhr

Das sind auch 2 verschiedene Strukturen. Die eine ist in der "parent-AppDomain", die andere in der "child-AppDomain".
Meines Wissens nach kannst du da nur etwas mit Reflection erreichen.
Vielleicht existiert aber auch irgend ein Attribute (wie StructLayout für unmanaged Com), mir ist allerdings kein solches bekannt.

mfg
SeeQuark

09.08.2009 - 12:29 Uhr

Das dürfte interessant für dich sein: Generieren und Kompilieren von dynamischem Quellcode oder CodeProject: Dynamic Code Integration with CodeDom
Google ansonsten einfach mal nach "CodeDOM".

mfg
SeeQuark

07.08.2009 - 21:57 Uhr

Wenn man ellenlange Schleifen und/oder if-Blöcke hat, mag das vielleicht sinnvoll sein.
Allerdings ist es kein schöner Stil, sie so lange zu machen.

A method should typically have 1-25 lines of code. If a method has more than 25 lines of code, you must consider refactoring it into separate methods.

Wenn man also vermeidet, solche langen Code-Blöcke zu schreiben (dein geposteter hat 34 Zeilen) hat man das Problem auch nicht 😄.

mfg
SeeQuark

07.08.2009 - 20:28 Uhr

Bei den Dependency Properties werden nicht die get und set Methoden aufgerufen, sondern Get- und SetValue(XXXProperty). Eigene Logik sollte man daher bei den Rückrufen und Validierungen von Abhängigkeitseigenschaften ausführen.

Um allerdings Veränderungen von Controls auszuführen, sollte man Bindings verwenden.
Da man das Aussehen von Controls üblicherweise in XAML definiert geht das Binding am Besten über das TemplateBinding.

mfg
SeeQuark

06.08.2009 - 23:12 Uhr

der hat kein .NET 2.0
und ich wollte dich schon auf Lambda-Expressions hinweisen 😃

Also der "normale" Mono-Compiler unterstützt Lambda-Expressions (Mono C# 2.0 and C# 3.0 compiler for CLI 2.0)

[PRE]
C# 2.0 (Auswahl)
 - generics
 - iterators (yield)
 - anonymous methods
C# 3.0 (Auswahl)
 - Language Integrated Query (LINQ)
 - implicitly-typed arrays
 - lambda expressions
 - automatic properties
 - extension methods
 - partial methods[/PRE]

Mit Unity3D kenne ich mich jetzt zwar nicht aus, aber in Getting started with C# for Unity3D werden "automatic properties" verwendet (habs aber auch nur überflogen).

mfg
SeeQuark

06.08.2009 - 22:20 Uhr

Schau dir mal die Implementation von der beiden Methoden aus ButtonBase an:

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    if (this.ClickMode != ClickMode.Hover) {
        e.Handled = true; // <== Da ist der Übeltäter
        base.Focus();
        if (e.ButtonState == MouseButtonState.Pressed) {
            base.CaptureMouse();
            if (base.IsMouseCaptured)
                if (e.ButtonState == MouseButtonState.Pressed)
                    if (!this.IsPressed)
                        this.SetIsPressed(true);
                    else
                        base.ReleaseMouseCapture();
        }
        if (this.ClickMode == ClickMode.Press) {
            bool flag = true;
            try {
                this.OnClick();
                flag = false;
            } finally {
                if (flag) {
                    this.SetIsPressed(false);
                    base.ReleaseMouseCapture();
                }
            }
        }
    }
    base.OnMouseLeftButtonDown(e);
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
    if (this.ClickMode != ClickMode.Hover) {
        e.Handled = true; // <== Da ist der Übeltäter
        bool flag = (!this.IsSpaceKeyDown && this.IsPressed) && (this.ClickMode == ClickMode.Release);
        if (base.IsMouseCaptured && !this.IsSpaceKeyDown)
            base.ReleaseMouseCapture();
        if (flag)
            this.OnClick();
    }
    base.OnMouseLeftButtonUp(e);
}

Die Lösung was siehst du auch gerade in den Methoden.
Bei OnMouseLeftButtonDown wird IsPressed auf true gesetzt, bei OnMouseLeftButtonUp wird das Click-Event ausgelöst.

Mich wundert es trotzdem ein bisschen, dass sie diese Events unterdrücken. Aber wenn du sie trotzdem willst, kannst du sie mit einer abgeleiteten Klasse wieder aktivieren, indem die die beiden oben gezeigten Methoden nochmal überschreibst und e.Handled auf false setzt.

mfg
SeeQuark

05.08.2009 - 23:49 Uhr

Das Einfachste wäre die Erweiterungsmethode Enumerable.ElementAt&lt;TSource&gt; (erst ab .NET 3.0 verfügbar).
Allerdings laufen alle solchen Lösungen auf IEnumerable heraus.

Besser wäre es da imho, eine normale List<T> zu verwenden, diese zu sortieren und dann den normalen Index zu verwenden.

Vielleicht noch interessant: [Übersicht] .NET Framework 2.X Auflistungen.

mfg
SeeQuark

05.08.2009 - 23:04 Uhr

Eigentlich müsste das schon so sein. Schau dir mal das an: XML-Dokumentation

[PRE]<see cref="member">  Eine Verknüpfung zu einem Mitglied oder Feld
                     in der aktuellen Kompilierungsumgebung [/PRE]

Eventuelle Schwierigkeiten bei der Überladung von Methoden werden da beseitigt.

mfg
SeeQuark

04.08.2009 - 22:23 Uhr

Siehe auch [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt unter dem Abschnitt Was bei Arrays zu beachten ist.

  
MyObject [] amyobj = new MyObject [20];  
amyobj [0].MyMethod (); // <== NullReferenceException,  
                        // weil das erste ArrayElement (amyobj [0]) null ist  

Oder kurz: inputArray[n] ist bei dir null.

mfg
SeeQuark

04.08.2009 - 22:03 Uhr

Weiter möchte ich vor dem "Haupt-GUI" ein Login-Fenster öffnen, wie geh ich da am Besten vor? Kann ich da einfach nach dem Initialisieren ein Popup erstellen, welches das Hauptgui sperrt?
Da kannst du in der App.xaml das StartupUri anpassen.
Damit startest du dann als erstes dein Login-Fenster. Und bei erfolgreichem Login startest du dann das Main Window.

Imho dürfte das erst klappen, wenn man den ShutdownMode ändert.

Daher würde ich das Popup im Konstruktor des Windows aufrufen.
Mit MVVM solltest du dir aber einen anderen Platz suchen, jedenfalls noch vor dem Öffnen deines Main Windows.

mfg
SeeQuark