Announcement

Collapse
No announcement yet.

Verarbeitung von voneinander abhängigen Benutzereingaben

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Verarbeitung von voneinander abhängigen Benutzereingaben

    Hallo .net-Gemeinde,

    Habe hier ein Logik-Problem bei dem ich nicht weiterkomme...

    Meine Form beinhaltet ca. 30 Textboxen, deren Eingaben alle mehr- oder weniger durch (mehrere) mathematische Formeln voneinander abhängig sind.
    Sind z.B. TXT1 und TXT2 bereits ausgefüllt, dann ergeben sich durch eine Eingabe in TXT3 die Werte von TXT4 und TXT5.
    Diese berechneten Werte sollen dann sofort in den Textboxen erscheinen.

    Jetzt soll es aber dem User überlassen sein, welche txt's er ausfüllen, und welche er berechnen lassen will. Ich weis also nicht von vorn herein welche txt's bereits bereits befüllt sind wenn ein Wert berechnet werden soll.

    Gibt es da elegantere bzw. bequemere Lösungen solche Eingaben zu behandeln, oder muss ich vor jeder Berechnung über if-else bzw. case abfragen welche txt's bereits befüllt sind?

    Hoffe ich konnte mein Problem einigermaßen verständlich erklären
    Danke für jede Hilfe,

    mfg
    Horst

  • #2
    Ich würde das evtl. so lösen. Du hast eine Klasse die Deine Logik repräsentiert. Irgendwo muss Deine Logik ja festgehalten sein:

    [highlight=c#]
    public class MathLogic
    {
    private double _field1; //Natürlich sollte man diese variablen nicht _field1 nennen, sondern ihnen einen sprechenden Namen geben. z.B. _height
    private double _field2;
    private double _field3;
    private double _field4;
    ...

    public MathLogic()
    {
    //Hier die Werte vorbelegen
    //Für eine Berechnung braucht alles zumindest einen Standardwert der in die Berechnung neutral einfließt

    _field1 = 1;
    _field2 = 1;
    _field3 = 1;

    _field4 = 0;
    _field5 = 0;
    }

    public void Calculate()
    {
    _field3 = _field1 * field2;

    _field5 = _field4 + _field3;
    }

    public double Field1
    {
    get { return _field1; }
    set { _field1 = value; }
    }

    //die restlichen genauso... man könnte auch auto-properties verwenden...
    }
    [/highlight]

    Dann definierst Du in deinem Formular eine BindingSource die auf die Klasse MathLogic verweist. Und einen Button der die Neuberechnung startet. Die Text Property der einzelnen Felder bindest Du an die entsprechende Eigenschaft der MathLogic Klasse.

    [highlight=c#]
    public class MyMathForm: Form
    {

    MathLogic _mathLogic;

    public MyMathForm()
    {
    InitialiseComponents();

    _mathLogic = new MathLogic();
    mathLogicBindingSource.DataSource = _mathLogic;
    }

    public void btnRecalculateClick()
    {
    _mathLogic.Calculate();
    mathLogicBindingSource.ResetBindings(false);
    }
    }
    [/highlight]

    So in etwa würd ichs versuchen zu organisieren. Ich hoffe Du verstehst wo ich hin will. Das ganze hab ich nicht getestet, sollte aber wohl funktionieren, wenn ich keinen Denkfehler hab

    Das tolle ist, dass die Rechenlogik komplett aus der Oberfläche herausgelöst ist. Könntest es praktisch mit derselben Rechenlogik auch eine ASP.NET Seite oder WPF Anwendung bauen
    Zuletzt editiert von fanderlf; 18.02.2010, 12:19.

    Comment


    • #3
      Hi fanderlf,

      danke für die schnelle Antwort!

      Ich bin mir aber nicht ganz sicher ob wir vom gleichen Problem sprechen...
      Mein Knackpunkt ist nicht die Anbindung der UI an die Logik (so habe ich deine Antwort verstanden), sondern der Umgang mit den Eingaben aus der UI in der Logik selbst.

      Wenn der User in deinem Beispiel z.B. _field1 und _field2 eingibt, muss _field3 berechnet werden, wird aber _field1 und _field3 eingegeben, muss _field2 berechnet werden, usw.
      Hinzu kommt noch, dass ein Eingabefeld von mehreren Formeln abhängig sein kann (die aber alle "zusammenpassen", also bei korrekter Eingabe das gleiche Ergebnis liefern), und ich wissen muss, ob alle Parameter einer solchen Formel eingegeben oder bereits berechnet wurden, ansonsten kann die Rechnung nicht durchgeführt werden.

      Bis jetzt habe ich das ungefähr so gelöst: (nur schematische funktionsweise)
      [highlight=vbnet]
      Sub Set_wert1 ()

      _wert1 = CInt(_field1.Text) 'Wert aus der TXT1 übernehmen

      if _wert2 > 0 then 'TXT2 bereits eingegeben
      _wert3 = _wert1 + _wert2 'Wert für TXT3 berechnen
      elseif _wert3 > 0 then 'TXT3 bereits eingegeben
      _wert2 = _wert3 - _wert1 'Wert für TXT2 berechnen
      end if

      if _wert4 > 0 then
      _wert5 = _wert1 / _wert4 'Wert für TXT5 berechnen
      end if

      End Sub
      [/highlight]
      Nur wurde jetzt das Projekt um ein vielfaches umfangreicher, sodass das Implementieren einer solchen Logik bei jedem Setzen eines Wertes einen extremen aufwand bedeutet bzw. auch schnell extrem kompliziert wird... daher bin ich auf der Suche nach einer einfacheren Lösung...

      mfg

      Comment


      • #4
        Mein Knackpunkt ist nicht die Anbindung der UI an die Logik (so habe ich deine Antwort verstanden), sondern der Umgang mit den Eingaben aus der UI in der Logik selbst.
        Die beiden Problemfelder gehören zusammen. Nehmen wir mal als Ausgangspunkt fanderlf's Code. Dort hast du für jede Wert eine Property die du einfach an die UI binden kannst. Aus den Settern der Properties würde ich die Calculate Methode aufrufen die die Berechnung vornimmt und die fehlenden Properties setzt. Durch das Binding wird dann automatisch die UI entsprechend angepasst. Du hast also den Code nur einmal in der Calculate Methode. Was du wie bei welcher Konstellation berechnen musst weißt aber nur du(zumindest bei unserer aktuellen Informationslage). Insofern können wir dir beim Inhalt der Calculate Methode nicht helfen es wird aber vermutlich so ähnlich aussehen wie deine Set_wert1 Methode.

        Comment


        • #5
          Ich denke das Hauptproblem besteht wohl darin, dass je nach Eingabesituation evtl. andere Formeln aufgerufen werden müssen? Hab ich das richtig verstanden?

          Da fiele mir auch eine Lösung dazu ein:

          [highlight=c#]
          public class MathLogic
          {
          private MathValues _mathValues = new MathValues();
          private IList<IFormula> _formulas = new List<IFormula>();

          public void Calculate()
          {
          BuildFormulaList();

          foreach(IFormula formula in _formulas)
          formula.Calculate(_mathValues);
          }

          private void BuildFormulaList()
          {
          _formulas.Clear();

          if(_mathValues.Field1 != null && _mathValues.Field2 != null)
          _formulas.Add(new FirstFormula());

          if(_mathValues.Field4 != null)
          _formulas.Add(new SecondFormula());
          }
          }

          public class MathValues
          {
          private double? _field1; //Natürlich sollte man diese variablen nicht _field1 nennen, sondern ihnen einen sprechenden Namen geben. z.B. _height
          private double? _field2; //double? bedeutet, dass der Wert auch NULL sein kann
          private double? _field3;
          private double? _field4;
          ...

          public MathValues()
          {
          //Hier die Werte vorbelegen
          //Für eine Berechnung braucht alles zumindest einen Standardwert der in die Berechnung neutral einfließt

          _field1 = null;
          _field2 = null;
          _field3 = null;

          _field4 = null;
          _field5 = null;
          }

          public double? Field1
          {
          get { return _field1; }
          set { _field1 = value; }
          }

          //die restlichen genauso... man könnte auch auto-properties verwenden...
          }

          private interface IFormula
          {
          void Calculate(MathValues mathValues);
          }

          public class FirstFormula: IFormula
          {
          public void Calculate(MathValues mathValues)
          {
          mathValues.Field3 = mathValues.Field1 * mathValues.Field2;
          }
          }

          public class SecondFormula: IFormula
          {
          public void Calculate(MathValues mathValues)
          {
          mathValues.Field5 = mathValues.Field3 + mathValues.Field4;
          }
          }
          [/highlight]

          Somit könntest Du anhand der gesetzten Werte in MathValues entscheiden, wann welche Formel angewandt wird. Du musst nur dafür Sorgen, dass leere Felder in der Benutzeroberfläche in der Klasse MathValues als NULL Werte übernommen werden. Du kannst auch nach jeder Berechnung wieder unterscheiden, welche die nächste einzusetzende Formel ist. So in etwa:

          [highlight=c#]
          public void Calculate()
          {
          if(_mathValues.Field1 != null && _mathValues.Field2 != null)
          new FirstFormula().Calculate(_mathValues);

          if(_mathValues.Field4 != null)
          new SecondFormula().Calculate(_mathValues);
          }
          [/highlight]

          Bei dieser Methode könnte man die Funktionen auch static machen oder sie auch gleich der Klasse selbst hinzufügen.
          Zuletzt editiert von fanderlf; 19.02.2010, 09:46.

          Comment


          • #6
            Sorry dass ich mich erst jetzt melde, hatte bisher keine Möglichkeit...

            Danke für eure Ideen/Lösungen, das letzte Beispiel von fanderlf scheint mir ziemlich genau das zu sein wonach ich gesucht habe
            Werd das ganze mal so implementieren und falls es probleme gibt meld ich mich nochmal.

            Thx und mfg,
            horst

            Comment

            Working...
            X