Comment lier un CheckBox à un DbColumn bool typé qui est annulable?

voix
4

Dans Windows Forms (.NET 2.0, Visual Studio 2005 SP1): J'ai tapé DataSet, avec une colonne type est System.Boolean, qui est annulable et dont la valeur par défaut est DBNull. J'ai Form, contenant une CheckBoxcommande qui je veux lier à la valeur de la colonne préalable.

  • J'ai essayé de lier la Checkedpropriété à la colonne via le concepteur: il fonctionne très bien, que si la valeur par défaut de la colonne est réglé sur Trueou False.
  • J'ai essayé de lier la CheckStatepropriété à la colonne par le concepteur, et fixer mes propres Formatet Parsegestionnaires d' événements , mais ils sont jamais appelé:

    b.Format+=delegate(object sender, ConvertEventArgs cevent) {
        cevent.Value=DoFormat((CheckState)cevent.Value); // cf. end of the question
    };
    b.Parse+=delegate(object sender, ConvertEventArgs cevent) {
        cevent.Value=DoParse(cevent.Value); // cf. end of the question
    };
    
  • Je l' ai essayé de créer une coutume par Bindingexemple dans le code, veuillez joindre mes gestionnaires d'événements et l' ajouter aux CheckBoxliaisons: les gestionnaires d'événements sont encore jamais appelés se ...

    Binding b=new Binding(CheckState, _BindingSource, MyColumn, false, DataSourceUpdateMode.OnPropertyChanged, DBNull.Value);
    

Comme une note: une DBNullvaleur est acceptable en venant de la DataSet(cela signifie que la valeur n'a jamais été définie). Mais l'utilisateur ne devrait être en mesure de définir la valeur Trueou Falsevia CheckBox.

Pour référence, voici le code de l'analyse syntaxique et de formatage méthodes:

internal static CheckState DoParse(object value)
{
    if ((value==null) || (value is DBNull))
        return CheckState.Indeterminate;

    bool v=Convert.ToBoolean(value);
    return (v ? CheckState.Checked : CheckState.Unchecked);
}

internal static object DoFormat(CheckState value)
{
    switch (value)
    {
    case CheckState.Checked:
        return true;
    case CheckState.Indeterminate:
        return DBNull.Value;
    case CheckState.Unchecked:
        return false;
    }

    return null;
}
Créé 13/08/2009 à 14:52
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
1

La façon easist Je sais, est tirer de la classe CheckBox, ajouter la propriété « DataValue » qui peut manipuler des valeurs DBNull et lier les données à la propriété « DataValue »:

public class DataCheckBox : CheckBox {
    public virtual object DataValue {
        get { return this.Checked; }
        set {
            if ( value == null || value is DBNull ) {
                this.CheckState = CheckState.Indeterminate;
            }
            else {
                this.Checked = (bool)value;
            }
        }
    }
}
Créé 18/08/2009 à 07:58
source utilisateur

voix
7

Avez-vous essayé lier CheckBox.CheckState au DataColumn sans y attacher Parse et des événements de format ou de déconner avec la liaison?

Malheureusement , je n'ai pas une instance de Visual Studio 2005 disponible mais je rassemblai une forme rapide dans Visual Studio 2008 et il a fait exactement ce que vous avez spécifié:

Comme une note: une valeur DBNull est acceptable en venant de l'DataSet (cela signifie que la valeur n'a jamais été fixée). Mais l'utilisateur ne devrait être en mesure de définir la valeur True ou False via la case correspondante.

Je peux être Parse, format ou reliure obtenir de votre manière ou il se peut que Windows Forms comporte différemment en 2008 qu'en 2005


Mise à jour le 18 août: Il fonctionne sur Visual Studio 2005 aussi à la fois par le concepteur et par le code. Voici le code qui le démontre de travail:


using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        DataTable table = new DataTable();
        public Form1() {
            InitializeComponent();

            //Creates the table structure
            table.Columns.Add("Name", typeof(string));
            table.Columns.Add("MyColumn", typeof(bool));

            //Populates the table with some stuff
            for (int i = 0; i < 5; i++) {
                table.Rows.Add(i.ToString());
            }

            //Creates the controls and puts them on the form.
            TextBox textBox = new TextBox();
            textBox.Location = new Point(10, 10);
            textBox.DataBindings.Add("Text", table, "Name");

            CheckBox checkBox = new CheckBox();
            checkBox.Left = textBox.Left;
            checkBox.Top = textBox.Bottom + 10;

            //Without true on the last argument, it will not work properly.
            checkBox.DataBindings.Add("CheckState", table, "MyColumn", true);

            Button previous = new Button();
            previous.Text = "";
            next.Top = previous.Top;
            next.Left = previous.Right + 5;
            next.Click += new EventHandler(next_Click);

            this.Controls.AddRange(new Control[] { textBox, checkBox, previous, next });
        }

        void next_Click(object sender, EventArgs e) {
            this.BindingContext[this.table].Position++;
        }

        void previous_Click(object sender, EventArgs e) {
            this.BindingContext[this.table].Position--;
        }
    }
}


Mise à jour le 23 août:

Pourquoi ça marche

La liaison a une méthode privée appelée formatObject qui est responsable de l'obtention d'une représentation de la valeur en provenance de la source de données qui est approprié pour être montré sur le contrôle.

Une fois le formatage est activé, Binding.FormatObject () passera par un chemin de code qui appellera les gestionnaires éventuels que vous avez pour l'événement Binding.Format. Si tout gestionnaire modifie la valeur se propageant de la source de données au contrôle par ConvertEventArgs.Value, cette valeur sera utilisée. Dans le cas contraire, il convoquera une formatter par défaut appelé formatObject sur une classe interne appelée System.Windows.Forms.Formatter.

Les commentaires sur l'état du code source:

« Le vrai travail de conversion se produit à l'intérieur FormatObjectInternal () »

Les commentaires pour l'état FormatObjectInternal:

« Réalise quelques conversions cas spéciaux (par exemple. Boolean à CheckState) »

A l'intérieur de FormatObjectInternal il vérifie si la valeur provenant de la source de données est nulle ou DBNull et si tel est le cas, il vérifie si le type de la propriété étant lié est de CheckState. Si tel est le cas, il retourne CheckState.Indeterminate.

Comme vous pouvez le voir, c'est un cas courant qu'il est une surprise, il ne fonctionne pas sur Windows Forms 1.x. Heureusement, le fixe sur 2.0 et au-delà.

Créé 18/08/2009 à 11:25
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more