Laden...
Avatar #avatar-3111.jpg
edsplash myCSharp.de - Member
Elektroingenieur i.A. Dabei seit 19.04.2008 390 Beiträge
Benutzerbeschreibung

Forenbeiträge von edsplash Ingesamt 390 Beiträge

08.06.2010 - 15:50 Uhr

In Flames ~ Delight and Angers

Ich war von ihrem "neuen" Album irgendwie ein Stück weit enttäuscht, obwohl es Stellenweise ganz gut ist. Hoffe das sie sich in zukünftigen Werken wieder vermehrt an Come Clarity/Reroute to Remain orientieren. Es bleibt aber eh abzuwarten, wie sie sich ohne Jesper entwickeln.

07.06.2010 - 21:22 Uhr

Hallo AchilL3zZ

Hauptsächlich mit Büchern, da meine Ausbildung im Bereich Programmieren kaum über Funktionen hinaus ging. Dazu kommen diverse Internet-Artikel, Blog-Einträge und nicht zuletzt über die Artikelserie auf dieser Seite, wo gewisse Sachen ganz gut erklärt werden. Gelesen hab ich dabei grundlegendes zu C#, OOA/D, Entwurfsmuster, DDD, O/R Mapping, Dependency Injection (bin ich atm gerade dran). Habe allerdings nicht für alles Bücher gekauft, da die genannten Artikel etc. teilweise ganz gut Aufschluss über das Thema bieten.

Gruss

03.06.2010 - 22:50 Uhr

Hm.. komisch! Muss mir das morgen nochmal anschauen.
Erachte die Aufgabe aber als gelöst 😉

03.06.2010 - 18:49 Uhr

Hallo

Bei int.MaxValue kommt immer noch 0 raus. Es geht ja nicht darum, ob int.MaxValue rein passt, sondern darum, ob die Genauigkeit mit grösseren Werten für CircleRadius erhöht wird. Und das ist momentan so nicht gegeben.

Gruss

03.06.2010 - 18:04 Uhr

Ich hätte eigentlich ganz gerne noch eine komplette Lösung 😉
Du darfst Dir aber gerne bereits eine neue Aufgabe überlegen.

03.06.2010 - 16:00 Uhr

Hallo MarsStein

Wenn man es einfach mit dieser Zahl multipliziert wird das natürlich nichts. Man könnte aber z.b. Next(0, CircleRadius) verwenden: Da wird das Ergebnis natürlich zunehmend ungenau, wenn CircleRadius kleiner wird.
An und für sich ist der Double allerdings genauer als ein Int32. Ich könnte mir aber vorstellen, dass die Operation mit Ganzzahlen schneller geht als mit Gleitkommazahlen, getestet habe ich das allerdings nicht.

Gruss

03.06.2010 - 15:26 Uhr

Erm nö, eigentlich nicht 😉

Nur scheint die Berechnung bei grossen Zahlen für CircleRadius zunehmend nicht mehr zu stimmen. Verwendet man z.b. int.MaxValue gibt es 0.

03.06.2010 - 10:40 Uhr

Hallo Zusammen

Hier die neue Aufgabe:
Es geht um die Berechnung von Pi mit Hilfe des Monte Carlo Algorithmus.

Zu implementieren ist folgendes Interface:


interface IMonteCarloPi
  {
    int CircleRadius { get; set; }
    double Calculate(int iterations);
  }

Die Methode Calculate berechnet Pi. Der Parameter iterations gibt an wie viel mal iteriert werden soll. Das Property CircleRadius ist dazu gedacht, die Genauigkeit zu erhöhen: Statt mit dem Einheitskreis zu arbeiten (Radius = 1) kann man einen grösseren Radius einstellen und so ein genaueres Resultat erhalten.

Gruss

02.06.2010 - 17:12 Uhr

Hallo

Du kannst für deine Elemente entweder einen eigenen Style definieren oder direkt ein eigenes ControlTemplate, da die Controls in WPF ja lookless sind. Da kannst du dann auch die ganzen Gradient-Effekte usw. reinpacken.

[edit]
Irgendwie kommt es mir so vor als ob du insgeheim Windows Forms meinst?
Dort gibt es entweder vorgefertigte 3rd Party Komponentenbibliotheken oder man darf in jedem Control das Paint Ereignis überschreiben und da selbst da selbst rumzeichnen.

[edit2]
Überleg Dir lieber zwei Mal, ob Du ein spezielles Aussehen für deine UI möchtest. Viele Benutzer finden es - vor allem bei professionellen Anwendungen - unangenehm, wenn man vom Standardaussehen der Windows Oberflächen abweicht. MediaPlayer und Co sind da wohl ausnahmen.

Gruss

02.06.2010 - 16:41 Uhr

Hallo..


    private static int FindRoute(char[,] map)
    {
      for (int column = 0; column < map.GetLength(1); column++)
      {
        int wayLenght = GetWayLength(map, 0, column, 1);
        if (wayLenght > 0)
          return wayLenght;
      }
      return 0;
    }

    private static int GetWayLength(char[,] map, int line, int column, int wayLength)
    {
      //Oberer Rand überschritten
      if (line == -1)
        return -1;
      //Linker Rand überschritten
      if (column == -1)
        return -1;
      //Rechter Rand überschritten
      if (column >= map.GetLength(1))
        return -1;

      if (map[line, column] == ' ')
      {
        map[line, column] = '+';

        if (line + 1 == map.GetLength(0))
          //Auf der letzten Zeile angelangt
          return wayLength;
        else
        {
          int rightNeighbor = GetWayLength(map, line, column + 1, wayLength + 1);
          int bottomNeighbor = GetWayLength(map, line + 1, column, wayLength + 1);
          int leftNeighbor = GetWayLength(map, line, column - 1, wayLength + 1);
          int topNeighbor = GetWayLength(map, line - 1, column, wayLength + 1);

          if (rightNeighbor > 0)
            return rightNeighbor;
          if (bottomNeighbor > 0)
            return bottomNeighbor;
          if (leftNeighbor > 0)
            return leftNeighbor;
          if (topNeighbor > 0)
            return topNeighbor;
          else
          {
            //Sackgasse
            //Bisher gegangener Weg löschen bzw. aktuelle Position wieder löschen
            map[line, column] = ' ';
            return -1;
          }
        }
      }
      else
      {
        return -1;
      }
    }

Wenn es zwei Wege gibt, werden zwar beide eingezeichnet, die Länge wird allerdings nur von einem zurückgegeben.

Gruss

01.06.2010 - 20:38 Uhr

Hallo

Die UML Diagramme in Textform beschrieben? Meinst Du vielleicht die Textanalyse, wo man einen Anwendungsfall in einer Prosaform beschreibt und daraus dann die Klassenkandidaten und deren Operatoren gewinnen kann?
Also bei mir wird das z.T. so eingesetzt in der Analysephase.

Gruss

01.06.2010 - 11:41 Uhr

Hallo rollerfreak2

Mit Spy++ lassen sich Windows Messages von Anwendungen beobachten. Sollte eigentlich mit VS2008 dabei sein!

Gruss

29.05.2010 - 11:25 Uhr

wunderbar harte Sounds aus Deutschland.

Dann darf man annehmen, dass Du auch Maroon, Maintain, Caliban und Konsorten kennst?

27.05.2010 - 10:33 Uhr

Versteh ich so wenig von Perl oder macht dieser Code überhaupt keinen Sinn?
Was hat denn if(...); für eine Wirkung? :S

26.05.2010 - 11:02 Uhr

Hallo Zusammen

Frei nach dem Motto "habe ich immer schon so gemacht, mache ich auch weiterhin so".

Ein solches Verhalten kenne ich aber auch von den Nutzern, wenn es um die Migration von alten Anwendungen geht: Man möchte es halt so, wie es bereits war. Nie wird in Frage gestellt ob man das überhaupt noch so braucht oder es nicht irgendwie besser und für den Nutzer angenehmer ginge.

21.05.2010 - 16:29 Uhr

Wie soll den IPV6 eingesetzt werden?
Kann es grundsätzlich sein, dass das gesamte Internet auf IPV6 basiert, ich aber in meinem lokalen Heimnetzwerk weiterhin IPV4 habe oder ist die Meinung, dass in Zukunft jedes Gerät eine eigene weltweit einmalige IP Besitzt? Trifft letzteres ein, kann man sich natürlich schon mal mit IPv6 fähigen Switches ausrüsten. Vorallem halte ich es für wichtig, dass ab sofort nurnoch IPv6 untersützende Hardware produziert wird. Das Argument, dass IPv6 für die Meisten nichts bringt stimmt schon aber das tut IPv4 auch nicht, wer braucht schon 4228250625 Adressen für sein Heimnetzwerk? Aber der Umstieg wäre dann wesentlich einfacher. Man kann sich so entschliessen irgendwann auf IPv6 umzusteigen ohne gleich neue Hardware zu kaufen.

Gruss

21.05.2010 - 15:17 Uhr

FileStream fs = new FileStream("Eine wohl noch nicht erstellte Datei", FileMode.Append);
fs.Close();

StreamWriter sw = new StreamWriter("die selbe Datei", true, Encoding.ASCII);
sw.Write("...");
sw.Close();


Ohne Worte 😁

19.05.2010 - 15:01 Uhr

Hm.. Ich denke ein paar Tage warten darf man schon: Und kann sich später höflich nach dem Status erkundigen.
Am besten gefällt mir aber das Sprichwort:

Das Rad, das am meisten quietscht wird zuerst geölt.

Ich denke es schadet nichts, sich höflich zu erkundigen ob sie die Bewerbung erhalten haben und ob alles recht ist etc.

Gruss

18.05.2010 - 11:59 Uhr

Bei mir ist es momentan As I Lay Dying mit ihrem neuen Album **The Powerless Rise **und daraus vor allem der Song Anodyne Sea

11.05.2010 - 10:00 Uhr

Hm okay..

Werde es bei Gelegenheit mal mit LinFu probieren.

Danke Euch beiden!

Gruss

10.05.2010 - 16:46 Uhr

verwendetes Datenbanksystem: SQLite

Hallo Zusammen

Ich arbeite z.Z. mit Fluent NHibernate. Ich habe mir bereits einige Klassen erstellt und die Mappings dazu. Nun ist es ja so, dass die Properties, die in die Datenbank gemappt werden sollen, virtual sein müssen. Soweit so gut: Nun möchte ich natürlich diesen Klassen Verhalten hinzufügen, welches nichts mit der Db zu tun hat und darum auch nicht gemappt werden soll. Beim Erstellen der Konfiguration bekomme ich aber die Fehlermeldung, dass eben diese Methoden nicht virtual sind und darum kein Proxy erstellt werden kann.

Warum probiert er die zusätzlichen Methoden ebenfalls mit einzubeziehen, obwohl diese im Mapping nicht erwähnt sind? Wenn ich alles als virtual deklariere, klappt es natürlich, aber das gefällt mir nicht so recht. Beim Automapping hätte ich es ja verstanden, wenn er prinzipiell alles zu mappen versucht aber dort wo ich noch explizit angebe, was gemappt werden soll und was nicht, nervt es mich ein wenig.

Gibts hier eine sinvolle Lösung?

TIA

Gruss

09.05.2010 - 19:45 Uhr

Hallo Zusammen

Gratulation auch von mir! (Nicht jeder hat einen persönlichen Wikipedia Artikel 😉

06.05.2010 - 14:02 Uhr

Habs nun gelöst:

https://connect.microsoft.com/VisualStudio/feedback/details/533935/referenced-assemblies-in-unit-test-are-not-copied-in-testresults-out

Scheint ein Bug zu sein:
Im Menü unter Test -> Testlaufkonfiguration bearbeiten -> Lokaler Testlauf und dann unter Bereitstellung/Deployment muss kann man die Ordner/Dateien hinzufügen, die zusätzlich kopiert werden sollen.

06.05.2010 - 13:55 Uhr

Es handelt sich um normale VS Testprojekte. Im Endeffekt ist es eine Assembly, die nicht an den richtigen Ort kopiert wird "NHibernate.ByteCode.Castle". Wenn ich im Testprojekt einen Verweis auf diese Assembly hinzufüge, wird sie zwar in den Ordner geladen, aber fehlt ihm dann immernoch die System.Data.SQLite Assembly, die im GAC liegt, sich aber nicht per <qualifyAssembly> laden lässt.

06.05.2010 - 12:38 Uhr

Hallo Zusammen

In meinem derzeitigen Projekt arbeite ich mit vielen Third-Party Libraries. Da diese Libraries teilweise wiederum andere Libraries referenzieren. Tritt häufig der Fall auf, dass eine Library dann eine weitere nicht findet. Dieses Problem kann man ja zunächst relativ einfach mit den Post-build Events lösen, und da einfach sämtliche Libs in den bin Ordner kopieren.
Nun möchte ich aus einer weiteren Anwendung natürlich meine geschriebene Library verwenden und muss auch da die Post-build Events nutzen, dass sich schlussendlich wieder alle verwendeten Libraries im bin Ordner der Anwendung befinden.
Das Problem ist nur, wenn ich nun ein Testprojekt erstelle, verfügt dieses zwar auch über einen bin/debug Ordner, wo ich die Libs reinkopieren könnte. Beim Test findet er diese jedoch nicht, da er in einem völlig anderen Ordner (TestResults/USERNAME_PCNAME DATUM/Out) nach den verweisen sucht.

Für diesen Ordner scheint es aber kein Post-build Makro zu geben, wo ich die Libs hinkopieren könnte. Die Idee etwas mit dem <probing> Element in der App-Config zu machen hatte ich auch schon, aber man scheint da nur auf Unterordner - und nicht übergeordnete oder absolute Pfade - verweisen zu können.

Gibt es eine saubere Lösung für dieses Problem? Alles in den GAC packen möchte ich eigentlich auch nicht.

05.05.2010 - 23:11 Uhr

[EDIT=herbivore]Obwohl die beiden Threads nicht 100%ig deckungsgleich waren, wegen der großen inhaltlichen Überschneidung zusammengefügt[/EDIT]

Hallo Zusammen

So ein Thread fehlt irgendwie noch 😉
Postet den Song, von dem ihr momentan nicht die Finger lassen könnt.

Ich mach mal den Anfang:
A Day to Remember - The Danger in starting a Fire genialer Song 😉 Live sind die aber noch besser 😮)

Ich wollte eigentlich einen "Was hört ihre gerade"-Thread machen, da dies aber möglicherweise zu sehr ausarten würde, wird es ein "Song of the day"-Thread, also postet bitte mit Maß.

[edit]**
herbivore hat mich darauf aufmerksam gemacht, dass YouTube Videos schwerlich vom Benutzer auf eine Copyright Verletzung geprüft werden können und es deshalb auch nicht in der Verantwortung des Benutzers liegen kann, das zu tun. Er muss sich darauf verlassen können, dass YouTube als legaler Anbieter dafür Sorge trägt, dass keine illegalen Inhalte angeboten werden. Deshalb sollten Links auf YouTube unproblematisch sein.**
[/edit]

edspLash`

04.05.2010 - 15:51 Uhr

Hallo herbivore

Da hast du ja was schönes erreicht. inflames2k hat List <T>genommen (und wenn auch das nicht erlaubt gewesen wäre, dann vermutlich Array, irgendworauf wird man ja sinnvollerweise aufbauen). Dadurch ist deine Bedingung formal erfüllt. Aber was hast du erreicht? Der Code ist auch nicht länger oder komplizierter als wenn man Dictionary<> verwendet hätte, aber um Größenordnungen weniger performant.

Hehe, ich hatte gedacht, jemand würde es ohne Dictionary ähnlich performant hinkriegen 😉 Mit dem Dictionary wird der Code allerdings weniger komplex, vorallem wenn man zwei davon verwendet -> Dictionary<TLeft, TRight> und Dictionar<TRight, TLeft>.

Hallo inflames2k

Deine Lösung scheint korrekt zu sein!

04.05.2010 - 13:59 Uhr

Hallo Zusammen

Meine Aufgabe:

Ziel ist es ein Interface IMap<TLeft, TRight> zu implementieren: ein IMap Objekt stellt quasi eine 1:1 Verknüpfung, bzw. eine eindeutige Zuordnung von Objekten verschiedenen Typs dar. Sowohl auf der linken, wie auf der rechten Seite darf nicht zweimal dasselbe Objekt vorkommen. Elemente der rechten Seite können dabei mit dem entsprechenden Element der linken Seite aus dem IMap Objekt geladen/beschrieben werden und umgekehrt.

Man sollte dabei sofern möglich vermeiden auf .NET Klassen wie Dictionary<T>, HashSet<T> zurück zu greifen. (Wäre ja langweilig 😃)


  interface IMap<TLeft, TRight>
  {
    /// <summary>
    /// Fügt der Map eine Zuordnung hinzu
    /// </summary>
    void Add(TLeft leftItem, TRight rightItem);

    /// <summary>
    /// Liest ein Element auf der rechten Seite der Map aus oder setzt dieses
    /// </summary>
    /// <param name="item">Ein Element auf der linken Seite, welches als Schlüssel dient</param>
    TRight this[TLeft item] { get; set; }

    /// <summary>
    /// Liest ein Element auf der linken Seite der Map aus oder setzt dieses
    /// </summary>
    /// <param name="item">Ein Element auf der rechten Seite, welches als Schlüssel dient</param>
    TLeft this[TRight item] { get; set; }

    /// <summary>
    /// Gibt an, ob auf der linken Seite ein spezifisches Element vorhanden ist
    /// </summary>
    bool Contains(TLeft item);

    /// <summary>
    /// Gibt an, ob auf der rechten Seite ein spezifisches Element vorhanden ist
    /// </summary>
    bool Contains(TRight item);

    /// <summary>
    /// Löscht eine Zuordnung
    /// </summary>
    /// <param name="item">Ein Element auf der linken Seite, welches als Schlüssel dient</param>
    bool Remove(TLeft item);

    /// <summary>
    /// Löscht eine Zuordnung
    /// </summary>
    /// <param name="item">Ein Element auf der rechten Seite, welches als Schlüssel dient</param>
    bool Remove(TRight item);

    /// <summary>
    /// Löscht alle Zuordnungen
    /// </summary>
    void Clear();

    /// <summary>
    /// Gibt die Anzahl der vorhandenen Zuordnungen zurück
    /// </summary>
    int Count { get; }
  }

Gruss

03.05.2010 - 22:41 Uhr

Hallo herbivore

Das mit dem Kirsch vs Kirsch halte ich nach wie vor für einen Schönheitsfehler, da der Quicksort Algorithmus ja sowieso nicht weiss, was er machen soll wenn zwei Werte gleich gross sind. Es ändert sich da Funktional also nichts. Habs aber trotzdem nachgebessert. 😉

Die Click Events hätte man allerdings generischer behandeln können, aber da hier gerne Quick&Dirty Lösungen präsentiert werden, bzw. das im ersten Beitrag erwähnt wird, ist das wohl auch nicht so Schlimm. 😉

Meine Aufgabe kommt dann Morgen. 😃

Gruss

03.05.2010 - 14:37 Uhr

Hallo herbivore

Hier meine Lösung!


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace Mcs
{
  class Program
  {
    [STAThread]
    static void Main(string[] args)
    {
      Application.EnableVisualStyles();

      Application.Run(new SortForm());
    }
  }

  class SortForm : Form
  {
    private ListBox sortedListListBox = new ListBox();
    private TextBox firstCompareTextBox = new TextBox();
    private TextBox secondCompareTextBox = new TextBox();
    private Button startSortingButton = new Button();
    private GroupBox compareGroupBox = new GroupBox();

    public SortForm()
    {
      InitializeComponent();
      sortedListListBox.Items.AddRange("Vanille, Schokolade, Stracciatella, Erdbeer, Zitrone, Kirsch und Schlumpf".Split(new string[] { ", ", " und " }, StringSplitOptions.RemoveEmptyEntries));
    }

    private void InitializeComponent()
    {
      //SortForm
      Height = 280;
      Width = 229;
      FormBorderStyle = FormBorderStyle.Fixed3D;
      Text = "UISort";
      MaximizeBox = false;

      //sortedListComboBox
      sortedListListBox.Top = 10;
      sortedListListBox.Left = 10;
      sortedListListBox.Width = 200;
      sortedListListBox.Height = 200;

      Controls.Add(sortedListListBox);

      //startSortingButton
      startSortingButton.Top = 215;
      startSortingButton.Width = 75;
      startSortingButton.Height = 23;
      startSortingButton.Left = 10;
      startSortingButton.Text = "Sort !1elf";
      startSortingButton.Click += StartSortingButton_Click;

      Controls.Add(startSortingButton);
    }

    private void PrepareComparisonControls()
    {
      //SortForm
      Width += 160;

      //compareGroupBox
      compareGroupBox.Top = 10;
      compareGroupBox.Left = 220;
      compareGroupBox.Width = 150;
      compareGroupBox.Height = 200;
      compareGroupBox.Text = "Compare";

      Controls.Add(compareGroupBox);

      //firstCompareTextBox
      firstCompareTextBox.Top = 15;
      firstCompareTextBox.Left = 10;
      firstCompareTextBox.Width = 100;
      firstCompareTextBox.Height = 23;
      firstCompareTextBox.ReadOnly = true;
      compareGroupBox.Controls.Add(firstCompareTextBox);

      //secondCompareTextBox
      secondCompareTextBox.Top = 43;
      secondCompareTextBox.Left = 10;
      secondCompareTextBox.Width = 100;
      secondCompareTextBox.Height = 23;
      secondCompareTextBox.ReadOnly = true;

      compareGroupBox.Controls.Add(secondCompareTextBox);
    }

    private void RemoveComparisonControls()
    {
      if (InvokeRequired)
      {
        Invoke(new Action(RemoveComparisonControls));
      }
      else
      {
        //Reset
        Width -= 160;
        Controls.Remove(compareGroupBox);
        compareGroupBox.Controls.Remove(firstCompareTextBox);
        compareGroupBox.Controls.Remove(secondCompareTextBox);
      }
    }

    private void StartSorting()
    {
      string[] elements = sortedListListBox.Items.Cast<String>().ToArray();
      UIComparer comparer = new UIComparer();

      comparer.ComparisonRequired += ComparisonRequired;

      ThreadPool.QueueUserWorkItem(
        new WaitCallback(o =>
      {
        Array.Sort<String>(elements, comparer);
        DisplaySortedResult(elements);
        RemoveComparisonControls();
      }), null);
    }

    private void DisplayComparison(CompareEventArgs e)
    {
      if (InvokeRequired)
      {
        Invoke(new Action<CompareEventArgs>(DisplayComparison), e);
      }
      else
      {
        firstCompareTextBox.Text = e.X;
        secondCompareTextBox.Text = e.Y;

        firstCompareTextBox.Click += (o, ea) => e.Chosen = e.X;
        secondCompareTextBox.Click += (o, ea) => e.Chosen = e.Y;
      }
    }

    private void DisplaySortedResult(String[] elements)
    {
      if (InvokeRequired)
      {
        Invoke(new Action<String[]>(DisplaySortedResult), ((Object)elements));
      }
      else
      {
        sortedListListBox.Items.Clear();
        sortedListListBox.Items.AddRange(elements);
      }
    }

    #region Events

    private void StartSortingButton_Click(Object sender, EventArgs e)
    {
      PrepareComparisonControls();
      StartSorting();
    }

    private void ComparisonRequired(Object sender, CompareEventArgs e)
    {
      DisplayComparison(e);
    }

    #endregion
  }

  class UIComparer : IComparer<String>
  {

    #region IComparer<string> Member

    public int Compare(String x, String y)
    {
      if (x == y)
        return 0;

      CompareEventArgs e = new CompareEventArgs(x, y);

      if (ComparisonRequired != null)
        ComparisonRequired.Invoke(this, e);

      e.WaitForUserInput();

      if (e.Chosen == x)
      {
        return 1337;
      }
      else
      {
        return -1337;
      }
    }

    #endregion

    public event EventHandler<CompareEventArgs> ComparisonRequired;
  }

  class CompareEventArgs : EventArgs
  {
    private String chosen = string.Empty;
    private AutoResetEvent waiter;

    public CompareEventArgs(String x, String y)
    {
      X = x;
      Y = y;
      waiter = new AutoResetEvent(false);
    }

    public void WaitForUserInput()
    {
      waiter.WaitOne();
    }

    public String X { get; set; }
    public String Y { get; set; }

    public String Chosen
    {
      get
      {
        return chosen;
      }
      set
      {
        chosen = value;
        waiter.Set();
      }
    }
  }
}


29.04.2010 - 08:51 Uhr

Wundert mich auch nicht 😉
Die Kommentare auf Heise sollte man sich allerdings lieber nicht antun.

27.04.2010 - 15:18 Uhr

Hallo Zusammen

[BTW]Ich verwende EF 1 und nutze die resultierenden Entities als DTOs, gebe diese also nicht an den Domain Layer weiter, sondern konvertiere diese zuerst in normale Domain Objekte.[/BTW]

Im Zusammenhang mit dem Repository Pattern und Relationen unter Tabellen, sind bei mir einige Fragen aufgetaucht.

Grundsätzlich geht man ja davon aus, dass pro Tabelle/DTO ein Repository mit den gängigen Methoden Add/Update/Remove/GetByID etc. existiert. Als Anwender eines solchen Repositories ist es klar, dass ich dem Repository ein Domänenobjekt übergebe, dieses Objekt dann vom Repository in ein DTO umgewandelt und schlussendlich an die DB gesendet wird.

Nehmen wir an, ich hätte eine Datenbank, wo ich Filme drin speichere. Dazu nutze ich 3 Tabellen: Film, Genre, und Film_Genre als Mappingtabelle, da vllt. ein Film mehreren Genres zuzuordnen ist aber es genauso mehrere mehrere Filme pro Genre gibt.
In der Domänenschicht verzichte ich jedoch auf ein Mappingobjekt und habe nur die DOs Film und Genre. Es gibt auch keine zirkularen Abhängigkeiten, da die Navigierbarkeit pro Anwendungsfall immer nur in eine Richtung laufen muss.

Filme sollen ja über das FilmRepository gespeichert werden und Genres über das GenreRepository. Nun kann und wird ein Film ja eine Liste mit Genres beinhalten. Sollte das FilmRepository von sich aus das GenreRepository aufrufen und dort die Genres abspeichern oder sollte man das dem Anwender des DALs überlassen, so dass er die Genres von Hand abspeichern muss? Eigentlich sollte ja aufgrund der Kapselung nicht noch der Benutzer die Genres eintragen; Eher sollte der DAL das automatisch machen!

Ein weiteres Problem stellt die Verwaltung der Relationen dar. Nun wurde ein Film aus der Datenbank geladen. Wieder enthält er ein paar Genres. Das Filmobjekt wird aber geändert: So wird dem Film z.B. ein weiteres Genre hinzugefügt, dass allerdings bereits in der Datenbank existiert. Beim Update passiert eigentlich nicht viel, die geänderten Daten des Films werden übertragen und da alle Genres bereits in der Datenbank existieren, muss im GenreRepository nichts gemacht werden. Was sich aber sehr wohl ändert, sind die Relationen zwischen Film und Genre. Die Mapping Tabelle müsste also aktualisiert werden und den Film mit dem neuen Genre verknüpfen. Allerdings ist mir nicht ganz klar, wer diese Relationen verwalten muss.
Müsste es ein weiteres Repository für die Relationen geben, wo der Anwender wiederum die Relationen von Hand nachtragen muss z.B. MappingRepository.AddRelation(Film, Genre) oder muss diese Aufgabe eines der beiden bestehenden Repositories übernehmen?

An der ersten Lösung gefällt mir nicht, dass trotz der Kapselung sich doch wieder der Anwender darum kümmern muss, dass die Relationen korrekt nachgetragen werden.
An der zweiten Lösung gefällt mir nicht, dass es sehr mühsam ist, das „geupdatete“ Objekt mit den Relationen in der Datenbank zu vergleichen: Man müsste ja zuerst schauen, ob im der Datenbank noch Relationen vorhanden sind, die es im aktuellen Objekt nicht mehr gibt und dann umgekehrt. Für eine Relation mag das funktionieren: Sobald allerdings Mehrere Tabellen und Mappingtabellen beteiligt sind, wird es ebenfalls mühsam.

Wie könnte ich dieses Problem am saubersten lösen?

TIA

23.04.2010 - 09:21 Uhr

Geht auch einfacher:

Naja.. ich würde eher sagen in weniger Zeilen, statt einfacher.

Grundsätzlich sind die geposteten Codebeispiele allerdings mit Vorsicht zu geniessen, man sollte nurmal probieren auch negative Zahlen auf 100 zu runden. -1566 ergibt nämlich kaum -1500!

Gruss

23.04.2010 - 07:57 Uhr

Hallo torti

Schon mal an die Modulo Funktion gedacht?

x = beliebige Zahl
rest = x mod 100
x -= rest

rest ≥ 50?
x+=100

Beispiel

x = 1234345
rest = 1234345 mod 100 = 45
x -= 45 = 1234300

45 ≥ 50? -> nö

x = 1234300!

Gruss

21.04.2010 - 07:26 Uhr

Hallo Blinideluxe

Ohne nun Deinen Beitrag genauer gelesen zu haben:

  1. Ist es normal die Hauptmethode ("takt") in der sich alles abspielt, in den Code
    von Form1 zu schreiben, statt irgendwie "Main" dazu zu nutzen?

  2. Ist es normal alle Variablen public zu machen damit alle Methoden darauf
    zugreifen können?

  3. (Was mir noch einfällt) Ist es irgendwie möglich eine Methode von Form1 aus
    Form2 aufzurufen ? Warum ist das bloß alles so gegeneinander abgeschirmt ?

  4. Ich habe irgendwo gelesen, dass man bei C# nicht mehr drum herum kommt
    objektorientiert zu programmieren, heißt das also ich programmiere bereits OO
    ohne es zu merken ?

  1. Jein: Zur Aktualisierung des GUIS i.o. das Spiel sollte aber selbstständig mit einem Tick laufen und das GUI sollte wirklich nur zur Anzeige der Spieldaten genutzt werden. (Auch eine Kollisionserkennung ist im GUI IMHO am falschen Platz)
    [edit] Sorry hab das Wort "takt" missinterpretiert: Deine Vorgehensweise ist wohl ein wenig suboptimal. Du kannst z.b. auf die KeyDown Events reagieren und die gedrückten Keys an die Spielklasse weiterschicken, die dann die Schlange entsprechend steuert. Die Aktualisierung des Spiels erfolgt mit einem internen Timer in der Spielklasse. Die beiden Wörter Endlosschleife und Application.DoEvents hören sich nicht sehr gut an. Siehe auch: [FAQ] Warum blockiert mein GUI? (Abschnitt: DoEvents ist Mist (:D))

  2. Kurz und Knapp: NEIN und dein Vorhaben hört sich stark "unobjektorientiert" an.
    Nur eine Klasse selbst sollte auf ihre Member zugreifen .

  3. Siehe hierzu: [FAQ] Kommunikation von 2 Forms

  4. Hehe.. dieses "ohne es zu merken" sollte dir die Antwort bereits geben: Man kommt in C# nicht drum herum Objekte zu verwenden. Mit objektorientierter Programmierung muss das allerdings lange nichts zu tun haben.
    Angenommen ich schreibe eine Konsolenapp und pappe alle Methoden die ich brauche in die Hauptklasse (und erst noch static), dann unterscheidet sich dieses Vorgehen IMHO kaum von einer Implementierung in einer nicht objektorientierten Sprache.

Gruss

19.04.2010 - 14:21 Uhr

Hm.. Ich bin mir nun nicht ganz sicher was Du möchtest.

Pseudocode



<Grid>
<WeiteresElement>
<... unbekannte Anzahl an Elementen (nicht vom Typ Grid)...>

<ZielElement BeliebigesProperty="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=EinAnderesProperty}" />

</... unbekannte Anzahl an Elementen (nicht vom Typ Grid)...>
</WeiteresElement>
</Grid>

Man kann so auf ein Elternelement/Ahnenelement zugreifen, ohne direkt einen Verweis oder einen Namen des Elements zu kennen.

Gruss

19.04.2010 - 10:27 Uhr

Hallo perlfred

wenn du den Namen festgelegt hast kannst du per DataBinding über


<Border BorderThickness="1" BorderBrush="Black" Width="{Binding ElementName=t_Tel, Path=Width}"></Border>

auf die Property des höhergelegenen Elements zugreifen.
Ansonsten, wenn man Namen oder das Element nicht direkt "kennt" und man nicht genau weiss, wie viele Elemente dazwischen sind, kann man auch über FindAncestor auf des höhergelegene Element zugreifen.


{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBlock}}, Path=Width}

Gruss

16.04.2010 - 11:52 Uhr

Hallo Schlopp

Aus diesem Grund habe ich auch das "noch" hineingepflastert. Mir ist natürlich klar, dass man sich gerade am Anfang nicht auf die Faule haut legen muss. Dieses "vorher schon gute Noten", war mehr drauf bezogen, dass ich mir wohl die Grundlagen nicht noch einmal zu Gemüte führen werde.

2x.. (weiss ich aber, dass wir das nicht können müssen. Umso besser wenn man es schon einmal gemacht hat 😉)

...geht das ein bisschen lockerer zu.
Der Student hat alle Freiheiten und entscheidet selbst ob er zu den Vorlesungen geht oder nicht.

...

Während der Vorlesungen sitzen etwa die Hälfte der Studenten (nur wenige Professoren haben was dagegen..) vor dem Notebook und hören mit einem Ohr dem Lecturer zu.

Das ist bei mir soweit ich richtig informiert bin von Fach zu Fach unterschiedlich.

Gruss

16.04.2010 - 09:31 Uhr

Hallo Zusammen

Gleich Vorweg: Es handelt sich um eine FH!

Es geht mir bei der Software auch ein wenig darum, dass ich mich wie z.B. bei der Idee mit OneNote vorher schon einmal ein bisschen darin bewegen kann und nicht am ersten Tag dann bereits mit der Bedienung überfordert bin.

Betreffend LaTeX ist es mir auch aufgefallen, dass wohl die Vorlagen ein wenig schwieriger sind.
Matlab muss ich mir mal anschauen: Kann man damit auch Gleichungen lösen etc.?

Die Idee mit dem Grafiktablett gefällt mir darum so gut, weil Windows 7 ja bereits einen handschriftlichen Formeleditor integriert hat.

Grundlagen in Mathe, E-Technik, Physik, ... beherrscht

Darüber mache ich mir (noch) keine grossen Sorgen: Habe in all diesen Fächern gute Noten gehabt, wobei ich sogar im letzten Jahr einen Vorbereitungskurs fürs Studium belegt habe, wo wir dann leichtes Ableiten, Integrieren und sogar komplexe Zahlen behandelt haben, obwohl das alles keine Voraussetzungen sind für das Studium. Ich habe auch schon von ehemaligen Auszubildenden gehört, dass man bei ETech etc. nochmals bei Adam und Eva beginnt.

PS: Studiparties sind ein guter Ausgleich zum Studium und um neue Kontakte zu knüpfen (man darf nach einer Party auch mal die ersten paar Lektionen fehlen :p)

😉

15.04.2010 - 23:18 Uhr

Hallo Zusammen

Diesen Herbst soll nun doch noch mein Studium starten (E-Techik).
Nun scheint es mir hier doch einige (Ex)Studenten zu geben und da wollte ich mich mal ein wenig informieren, wie man sich am besten aufs Studium vorbereiten kann. Vielleicht habt ihr auch irgendwelche Tipps wie man sich den Alltag organisieren soll.

Gibt es vielleicht Sachen in die ich mich einarbeiten sollte (LaTeX, sonstige Programme)?
Muss ich mir vorher Gedanken über Dokumentenverwaltung o.Ä. machen?
Lohnt sich die Anschaffung eines Grafiktabletts zur Erfassung von Notizen oder Formeln, welche Programme würden sich dazu eignen?
Gibt es irgendwelche Mathematik-Programme die man sich vorher anschauen sollte, da deren Bedienung relativ schwer ist?
Welche Programme nutzt man zum Verfassen von Arbeiten/Zusammenfassungen oder das Plotten von Funktionen etc.?

Fragen über Fragen 😉

Vielen Dank im Voraus

14.04.2010 - 23:26 Uhr

Es geht doch ganz einfach:


while(this.NetWorkStream.DataAvailable)
{
}

als Schleifenbedingung nutzen und die Schleife bricht ab, sobald keine Daten mehr vorhanden sind!

Oder habe ich das Problem falsch verstanden 🤔

Gruss

14.04.2010 - 13:02 Uhr

Irre ich mich oder geht es dabei nur um die Server Version?

Auf der Homepage ist die aktuellste Client Version nach wie vor 1.7.7.

Gruss

14.04.2010 - 00:03 Uhr

Zwischendurch solltest Du aber den MemoryStream mit

  
buffer.WriteTo(fileStream)  
  

wieder in den FileStream rüberschieben.

Das gilt natürlich nur, wenn Du es schlussendlich in einem File speichern möchtest und der Speicherverbrauch der Anwendung nicht in die Höhe schnellen soll, wenn du z.B. eine 100Mb Datei lädst.

Gruss

13.04.2010 - 22:57 Uhr

Hallo

(In der Annahme, dass ich das Problem richtig verstanden habe.)



//aus dem Stegreif
MemoryStream buffer = new MemoryStream();

BinaryWriter writer = new BinaryWriter(buffer);

Zwischendurch solltest Du aber den MemoryStream mit


buffer.WriteTo(fileStream)

wieder in den FileStream rüberschieben.

[EDIT]
Verwende doch bitte bei CSharp Code die entsprechenden BB Tags

MemoryStream

Gruss

13.04.2010 - 09:13 Uhr

Hallo

Ich habe es nun über einen AttachedBehavior gelöst:


class ColumnsBehavior
  {
    private static Dictionary<Object, DependencyObject> mappings = new Dictionary<Object, DependencyObject>();

    public static readonly DependencyProperty MyColumnsProperty = DependencyProperty.RegisterAttached(
      "MyColumns",
      typeof(ObservableCollection<DataGridColumn>),
      typeof(ColumnsBehavior),
      new UIPropertyMetadata(
        new ObservableCollection<DataGridColumn>(), 
        new PropertyChangedCallback(MyColumnsChanged)
        )
      );

    public static void SetMyColumns(DependencyObject element, ObservableCollection<DataGridColumn> cols)
    {
      element.SetValue(MyColumnsProperty, cols);
    }

    public static ObservableCollection<DataGridColumn> GetMyColumns(DependencyObject element)
    {
      return (ObservableCollection<DataGridColumn>)element.GetValue(MyColumnsProperty);
    }

    private static void SourceChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
      DataGrid target = (DataGrid)mappings[sender];

      if (e.Action != NotifyCollectionChangedAction.Move)
      {
        if (e.OldItems != null)
        {
          foreach (Object item in e.OldItems)
          {
            target.Columns.Remove((DataGridColumn)item);
          }
        }

        if (e.NewItems != null)
        {
          foreach (Object item in e.NewItems)
          {
            target.Columns.Add((DataGridColumn)item);
          }
        }
      }
      else
      {
        target.Columns.Move(e.OldStartingIndex, e.NewStartingIndex);
      }
    }


    private static void MyColumnsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
      DataGrid target = (DataGrid)o;

      if (target == null)
        throw new ArgumentException("o");

      ObservableCollection<DataGridColumn> columns = (ObservableCollection<DataGridColumn>)e.NewValue;

      foreach (DataGridColumn column in columns)
      {
        target.Columns.Add(column);
      }

      if (e.OldValue != null)
        mappings.Remove(e.OldValue);

      mappings.Add(columns, o);

      columns.CollectionChanged += SourceChanged;
    }
  }

Verwendung:


<d:DataGrid x:Name="MyDataGrid" 
                ItemsSource="{Binding Items}" 
                AutoGenerateColumns="False" my:ColumnsBehavior.MyColumns="{Binding Columns}">
</d:DataGrid>

Gruss

12.04.2010 - 16:17 Uhr

Hallo Zusammen

Gibt es eine Möglichkeit die Columns Eigenschaft des DataGrids irgendwie per Laufzeit festzulegen? Da das Columns Property ReadOnly ist schlägt der Versuch, da mit Binding oder Styles was zu machen, natürlich fehl.
Gäbe es sonst eine Möglichkeit verschiedene Datentypen mit verschiedenen Columns anzuzeigen ohne AutoGenerateColumns="True" zu verwenden?

Was ich mir noch überlegt habe ist: Ein Default Style für den DataGrid; Pro Datentyp der angezeigt werden muss ein DataGrid definiert die DataGrid Instanz mit DynamicResource o.Ä. zur Laufzeit ändern. Diese Vorgehensweise gefällt mir aber irgendwie nicht so richtig.

Gruss

09.04.2010 - 12:16 Uhr

Ich wollte vor kurzem auch alle meine Anwendungen signieren. Leider kann man das Ganze vergessen wenn man unsignierte 3rd Party Assemblies verwendet. Es gibt zwar Methoden umd fremde Assemblies nachträglich zu signieren. Der Aufwand rechtfertigt sich aber IMO nicht mehr.

08.04.2010 - 19:59 Uhr

Willst du denn genau das gleiche erreichen? Also auch ein physich nicht vorhanden Bytestream in den Explorer kopieren?

Ja Prinzipiell.

Gäbe ja noch die Möglichkeit ein eindeutiges, temporäres File zu übergeben und sich mit einem File System Watcher den Pfad zu holen, wo die Datei hinverschoben wird.

Ich glaube aber gelesen zu haben, dass dieses Problem auch über Shell Extensions zu lösen wäre und darum habe ich gefragt. 😉

Gruss

08.04.2010 - 19:27 Uhr

Im embedded Bereich wird noch um jedes Kilobyte gekämpft und es wird Schnelligkeit gefordert (ms und µs Bereich), das bestimmt ja auch den Preis des Endgeräts.

Es fragt sich halt wo man das Geld investieren will. Wird in C programmiert kann man die schwächeren und günstigeren Prozessoren wählen. Dafür kann man C++ Code später noch erweitern und holt so das Geld für die teureren Prozessoren wieder rein. 😉

07.04.2010 - 20:03 Uhr

Hallo Khalid

Wäre es mit den Managed Shell Extensions nun theoretisch möglich auf das Drop Event des Explorers zu reagieren? Da gibt es ja viele sehr komplizierte und nur knapp funktionierende (wie z.b. hier besprochen) Lösungsansätze.

Gruss