Announcement

Collapse
No announcement yet.

DateTimePicker.ShowCheckBox und die Checked Property

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

  • DateTimePicker.ShowCheckBox und die Checked Property

    Servus zusammen!

    <br>
    <br>

    Ich habe eine Frage: Ich habe einige DateTimePicker, die ich gerne mittles ihrer Checkbox per DataBinding (an einen bool Wert) disablen würde, und zwar so lange bis der User sie enabled.
    <br>
    Nur wie ich das sehe, dient ja diese Checked Property irgendwie einem anderen Zweck.
    Weil sie setzt sich selber munter auf true (so wie ich das verstanden hab wenn ein gültiger Wert in ihr angezeigt wird?! ).
    <br>
    Verstehe ich hier was ganz gewaltig nich, oder kann ich diese Property nicht für meine Zwecke missbrauchen?
    <br>
    Es müssen in keinster Weise irgendwie Werte validiert werden oder so etwas. Ich hätte einfach nur gerne DateTimePicker, die mittels dieser checkbox enabled/disabled werden können (und ihren Zustand dann halten, bis der User ihn ändert).
    <br>
    Klar kann ich auch einfach ne normale Checkbox ohne Text davorkleben, aber die Checkbox in dem DateTimePicker is doch schon ne Ecke hübscher
    <br>

    <br>
    Grüsse, Ronald

  • #2
    Hallo,
    das DateTimePicker-Control hat eine Eigenschaft <b>ShowCheckBox</b> mit der im DateTimePicker eine kleine CheckBox angezeigt wird. Sobald diese Eigenschaft den Wert true hat, läßt sich die CheckBox über die Eigenschaft <b>Checked</b> steuern. Wenn Checked den Wert False zugewiesen bekommt, ist der DateTimePicker disabled und zeigt "keinen" Datums-Wert an (exakt formuliert, wird der aktuelle Tag in grauer Schrift angezeigt). Das folgende Beispiel zeigt eine mögliche Alternative zur Steuerung, indem die Ereignisse <b>Format</b> und <b>Parse</b> ausgenutzt werden:
    <code>
    <b>private</b> CurrencyManager aCM;

    <b>private</b> <b>void</b> OnTestDatumParse(<b>object</b> sender, ConvertEventArgs e)
    {
    <b>if</b> (! <b>this</b>.dateTimePicker1.<b>Checked</b>)
    {
    <font color="#003399"><i>/*
    * Kann laut .NET Framework SDK-Dokumentation nicht funktionieren, da nur ein gültiges
    * Datum erlaubt ist:
    * &quot;Gets or sets a value indicating whether the Value property has been set with a valid
    * date-time value and the displayed value is able to be updated.&quot;
    */</i></font>
    e.Value = System.DBNull.Value;
    System.Diagnostics.Trace.Write(<font color="#9933CC">&quot;NULL zugewiesen&quot;</font>);
    }
    }

    <b>private</b> <b>void</b> OnTestDatumFormat(<b>object</b> sender, System.Windows.Forms.ConvertEventArgs e)
    {
    <b>if</b> (e.Value == System.DBNull.Value)
    {
    <b>this</b>.dateTimePicker1.<b>Checked</b> = <b>false</b>;
    System.Diagnostics.Trace.Write(<font color="#9933CC">&quot;Format: DBNull erkannt&quot;</font> + Environment.NewLine);
    }
    <b>else</b>
    {
    <b>this</b>.dateTimePicker1.<b>Checked</b> = <b>true</b>;
    System.Diagnostics.Trace.Write(<font color="#9933CC">&quot;Format: Datum erkannt&quot;</font> + Environment.NewLine);
    }
    }

    <b>private</b> <b>void</b> Form1_Load(<b>object</b> sender, System.EventArgs e)
    {
    <b>this</b>.sqlDataAdapter1.Fill(<b>this</b>.dataSet11);
    aCM = (CurrencyManager)BindingContext[dataSet11, <font color="#9933CC">&quot;DTPDemo&quot;</font>];
    Binding aB = <b>new</b> Binding(<font color="#9933CC">&quot;Text&quot;</font>, dataSet11, <font color="#9933CC">&quot;DTPDemo.TestDatum&quot;</font>);
    aB.Parse += <b>new</b> ConvertEventHandler(<b>this</b>.OnTestDatumParse);
    aB.Format += <b>new</b> ConvertEventHandler(<b>this</b>.OnTestDatumFormat);
    <b>this</b>.dateTimePicker1.DataBindings.Add(aB);
    }

    ....
    </code&gt

    Comment


    • #3
      Hallo Hr. Kosch!
      <br>
      Abermals vielen Dank für ihre Hilfe.
      Ein paar Fragen zu ihrer Lösung hätte ich jedoch:
      <br>
      Wofür lassen sie ich den CurrencyManager geben?
      (vorausgesetzt, das ist das was hier:
      aCM = (CurrencyManager)BindingContext[dataSet11, "DTPDemo"];
      geschieht).
      <br>
      Muss ich in die DatenBank explizit sowas wie NULL (DBNull?) schreiben, damit beim Laden des Dialogs der DateTimePicker automatisch disabled wird (bzw. müsste ich dafür ihr Beispiel noch erweitern?
      Ich hatte es mal testweise so in mein Programm übernommen,
      aber da wo in meiner Tabelle noch kein Datumseintrag ist, war der DateTimePicker trotzdem aktiviert.
      <br>
      Grüsse, Ronal

      Comment


      • #4
        Hallo,

        &gt;Wofür lassen sie ich den CurrencyManager geben?

        die Punkte am Ende des Beispiel sollen zeigen, dass es dort noch weitergeht (und der folgende Teil braucht den CurrencyManager).
        <br>
        &gt;..war der DateTimePicker trotzdem aktiviert.
        Welchen Output generiert <i>System.Diagnostics.Trace.Write</i> in diesem Fall. Die Auswertung <i>if (e.Value == System.DBNull.Value)</i> muss an die eigenen Bedingungen angepasst werden. Mein Beispiel geht davon aus, das die Datenbanktabelle (MS SQL Server-Datenbank tempdb) den folgenden Aufbau nutzt:
        <code>
        USE tempdb
        GO

        CREATE TABLE DTPDemo (
        DTPDemoID INTEGER NOT NULL IDENTITY PRIMARY KEY,
        Testeintrag VARCHAR(30) NOT NULL,
        TestDatum DATETIME )
        GO

        INSERT INTO DTPDemo (Testeintrag,TestDatum) VALUES ('Testeintag 1', '01.01.2002');
        INSERT INTO DTPDemo (Testeintrag,TestDatum) VALUES ('Testeintag 2', '18.12.2002');
        INSERT INTO DTPDemo (Testeintrag,TestDatum) VALUES ('Testeintag 3', '19.12.2002');
        INSERT INTO DTPDemo (Testeintrag) VALUES ('Testeintag 4');
        GO

        </code>
        Das Datum wird in einer Spalte vom Typ DATETIME gespeichert. Beim letzten INSERT-Aufruf wird kein Datumswert eingefügt, so dass in der Datenbank der Zustand NULL gespeichert wird

        Comment


        • #5
          achso, ich werde es mir nochmal angucken, danke!
          <br>
          Zwar habe ich es anders realisiert (aus Design und Verständlichkeitsgründen für die User), aber mann will ja auch was lernen!
          <br>
          Vielen Dank für die Hilfe

          Comment


          • #6
            Eine Frage würde ich gerne noch dazu anhängen:
            Kann ich die Parse/Format Events generell dazu benutzen, mich zwischen das DataBinding zu schalten?
            Zwar sind meine Checkboxen nun einzeln und nicht mehr davor, aber das sollte dem Prinzip doch keinen Abbruch tun, sodass ich doch wieder ihre Lösung sehr gut gebrauchen könnte.<br>
            Meine Löung funktioniert dann nämlich doch nicht, da der Commandbuilder UpdateCommands generiert, die meckern wenn die Daten anders geändert wurden (ein feature, das ich erstmal gerne behalten würde).<br>
            Also die Funktionalität ihres Beispiels sollte doch unabhängig davon sein, ob ich checkboxen IN den DateTimePickern habe oder separate, oder

            Comment


            • #7
              so nach einigem Rumgebastel und dem Versuch es anders zu lösen bin ich nun doch wieder hier angekommen.
              Zwar benutze ich jetzt nicht mehr die Checkboxen des DateTimePickers sondern nur noch einzelne Checkboxen (aus Design Gründen), aber das sollte ja egal sein.<br>
              Mein Format Event funktioniert soweit so gut, es aktiviert/deaktiviert die Checkbox abhängig vom Inhalt des Feldes der Datenbank.<br>
              Was leider gar nicht geht ist das Parse-Event. Dieses bekomme ich leider nicht mal ausgelöst.
              Laut MSDN würde es ausgelöst nach
              * dem Validated Event des Controls ( bei mir gibbets nix zu validaten, aber egal, ich hab das Validated Event ausgelöst, nix passiert)
              * nach der EndCurrentEdit Methode der BindingManagerbase. Um dieses zu erreichen, habe ich den Currency Manager benutzt :
              CurrencyManager cm = (CurrencyManager)BindingContext[Ergo.MainApp._DesignDB._DesignDS, "Zeichnungen"];
              cm.EndCurrentEdit();
              Bringt leider auch nix.
              * eine Änderung des Current Objektes der BindingManagerBase.
              Nun ja was anders als die SchummeltestLösung
              cm.Position += 1;
              ist mir da leider nicht eingefallen. Bringt aber auch nix.<br>
              Bin leider nachwievor ein Anfänger was .Net betrifft (und generell wohl eher auch was programmieren angeht), von soher nicht wundern wenn ich hier Grundlegendes nicht peilen sollte <br>
              Ach ja, System.Diagnostics.Trace.Write generiert leider erstmal gar nix in meinem Fall, zumindest sehe ich davon nix.
              Und wenn ich mir in der MSDN all das anschaue, was man machen muss für einen eigenen TraceListener, nun ja...
              Aber wenn ich das richtig verstanden hab schreibt doch Trace.Write auch nur den String den ich ihm gegeben hab, oder?
              Demensprechend müsste ne Simple Msgbox da "ausreichend" sein um zu sehen ob das Event geraised wird.
              Und es wird leider nicht geraised..

              Comment


              • #8
                Hallo,
                wie die beigefügte Abbildung zeigt, wird in meinem Beispiel sowohl Format als auch Parse ausgelöst. Anstelle von <i>System.Diagnostics.Trace.Write</i> hilft auch eine schlichte ListBox weiter, in der über <i>Add</i> das Aufrufen der Ereignisbehandlungsmethoden mitprotokolliert wird

                Comment


                • #9
                  Hallo Hr. Kosch,
                  ich glaube ihnen ja vom Fleck weg, das ihr Beispiel funktioniert.
                  Mein Problem ist ja leider, das ich es nicht reproduzieren kann
                  Sehe ich das richtig, das in sie in ihrem Testprogram mittels der > < Buttons zwischen den Datensätzen navigieren?
                  Ich denke mal, das sie dann dabei explizit die Position Property des Currency Managers setzen.
                  So etwas in der Form geschieht bei mir nicht explizit (wenn höchstens automatisch durch das Binding), und der Versuch das per Hand zu setzen schlug leider fehl.
                  Aber so wie ich es verstanden habe ist dies ja eine der Bedingungen welches das Parse Event auslöst.<br>
                  Wissen sie zufällig welche Zeile bzw. welcher Zusammenhang in ihrem Code explizit für das auslösen des Events zuständig ist?<br>
                  P.S.: bin ihnen wirklich sehr dankbar dass sie mir helfen

                  Comment


                  • #10
                    macht es einen Unterschied ob mein DataBinding an die Text Property oder an die Value Property gesetzt ist?

                    Wie gesagt, es geht mir primär um das Auslösen des Events, noch nicht um das Bearbeiten irgendwelcher Daten...

                    Und das ich MessageBoxen anstatt einer Listbox benutze sollte ja egal sein, oder?
                    Es geht ja nur darum zu sehen ob ich das Event auslöse...<br>
                    Edit: Ich verstehe es nicht. Selbst wenn ich mein Validated Event auslöse
                    (Zitat MSDN: The Parse event occurs under the following conditions:
                    after the Validated event of the Control object occurs. ) passiert nix, die MessageBoxen in meinem Parse Event sind nicht zu sehen, genauso wenig wird der andere Code im Event ausgeführt.
                    Herrschaftszeiten noch eins...
                    &#10

                    Comment


                    • #11
                      Hallo,
                      das Verändern des "virtuellen Datensatzzeigers" über die Button ist nicht notwendig, dass Ereignis Parse wird auch dann ausgelöst, wenn die CurrencyManager-Methode <b>EndCurrentEdit</b> direkt aufgerufen wird:
                      <code>
                      <b>private</b> <b>void</b> Form1_Load(<b>object</b> sender, System.EventArgs e)
                      {
                      <b>this</b>.sqlDataAdapter1.Fill(<b>this</b>.dataSet11);
                      aCM = (CurrencyManager)BindingContext[dataSet11, <font color="#9933CC">&quot;DTPDemo&quot;</font>];
                      Binding aB = <b>new</b> Binding(<font color="#9933CC">&quot;Text&quot;</font>, dataSet11, <font color="#9933CC">&quot;DTPDemo.TestDatum&quot;</font>);
                      aB.Parse += <b>new</b> ConvertEventHandler(<b>this</b>.OnTestDatumParse);
                      aB.Format += <b>new</b> ConvertEventHandler(<b>this</b>.OnTestDatumFormat);
                      <b>this</b>.dateTimePicker1.DataBindings.Add(aB);
                      }

                      <b>private</b> <b>void</b> buttonEndCurrentEdit_Click(<b>object</b> sender, System.EventArgs e)
                      {
                      aCM.EndCurrentEdit();
                      }
                      </code>
                      Erst dann, wenn die Daten von der Benutzeroberfläche (Control) in die DataTable-Instanz im DataSet übernommen werden, wird das Ereignis Parse ausgelöst. Und diese Übernahme findet zu 2 alternativen Zeitpunkten statt: <br>
                      1. Der CurrencyManager ändert seine Position, oder <br>
                      2. Die CurrencyManager-Methode EndCurrentEdit wird aufgerufen.
                      &#10

                      Comment


                      • #12
                        hm dann habe ich es richtig verstanden nur irgendwo einen Haken bei mir...
                        Ein letzter Versuch, ich hoffe sie nehmen sich noch einmal die Zeit dafür
                        Alle Bindings sind auf einen DataView.
                        Hier ist aller relevanter Code für dieses Binding:
                        <br>Hier das Binding und der Currency Manager:

                        <br>myCM = (CurrencyManager)BindingContext[Ergo.MainApp._DesignDB_SelDesignDV];
                        if(myCM != null) MessageBox.Show("is not null");
                        Binding bind = new Binding("Text", Ergo.MainApp._DesignDB._SelDesignDV, "Freigabe_Datum");
                        bind.Parse += new ConvertEventHandler(bind_Parse);
                        bind.Format += new ConvertEventHandler(bind_Format)
                        this.dTP_Freigabe.DataBindings.Add(bind);<br>

                        <br>Hier die Events:<br>
                        <br>private void bind_Format(object sender, ConvertEventArgs e)
                        {
                        if (e.Value.ToString() == "")
                        this.chBx_Freigabe.Checked = false;
                        else
                        this.chBx_Freigabe.Checked = true;
                        }

                        private void bind_Parse(object sender, ConvertEventArgs e)
                        {

                        MessageBox.Show("Holla");
                        if (!this.chBx_Freigabe.Checked )
                        e.Value = "";
                        else
                        e.Value = this.dTP_Freigabe.Text;
                        }
                        <br>Und hier, in meiner Savefunktion der Aufruf der EndCurrentEdit und der Upload der Daten....

                        <br>myCM.EndCurrentEdit();
                        Ergo.MainApp._DesignDB.UploadDataView(bc);

                        <br>und letzere Upload Funktion sieht so aus:
                        <br>public void UploadDataView(BindingContext bc)//
                        {
                        bc[selDesignDV].EndCurrentEdit();
                        OleDbCommandBuilder cb = new OleDbCommandBuilder(designDA);
                        try
                        {
                        designDA.Update(designDS, "Zeichnungen");
                        }
                        catch(Exception ex)
                        {
                        MessageBox.Show(ex.Message, "Fehler beim Upload der Daten - UploadDataView");
                        }
                        }

                        <br>Alle anderen Datenupdates funktionieren einwandfrei, also glaub ich eher nicht, das der Fehler da liegt.
                        Das Format Event funktioniert wie gesagt ebenfalls.
                        Die MessageBox im Parse Event erscheint nicht (eine im Format Event war stets zu sehen, und Daten kommen in der DB auch nicht an....
                        Ich hoffe sie können den Fehler sehen

                        Comment

                        Working...
                        X