Jak svázat políčka boolovské zadaný DbColumn, který je s možnou hodnotou Null?

hlasů
4

Ve Windows Forms (.NET 2.0, Visual Studio 2005 SP1): Mám napsaný DataSet, s kolonou, který typ je System.Boolean, který je s možnou hodnotou Null a který Výchozí hodnota je DBNull. Mám Form, obsahuje CheckBoxovládací prvek, který chci vázat na hodnotu předchozího sloupce.

  • Snažil jsem se svázat Checkedvlastnost sloupce přes konstruktéra: funguje to skvěle, jen v případě, že výchozí hodnota pro sloupec je nastaveno buď Truenebo False.
  • Snažil jsem se svázat CheckStatevlastnost sloupce přes konstruktéra a upevnění své vlastní Formata Parseudálosti rutiny, ale nikdy s názvem:

    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
    };
    
  • Snažil jsem se vytvořit vlastní Bindinginstanci v kódu, připojte své rutiny událostí a přidat ji do CheckBoxvazby: obslužné rutiny událostí jsou ještě nikdy volán ...

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

Jako Poznámka: DBNullhodnota je přijatelná pouze v případě, vycházejícího z DataSet(to znamená, že hodnota nebyla nikdy nastaveny). Ale uživatel by měl být schopen nastavit hodnotu pouze na Truenebo Falsepřes CheckBox.

Pro porovnání je zde kód parsování a formátování metod:

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;
}
Položena 13/08/2009 v 14:52
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
1

Nejjednodušší cesta k nám Já vím, je odvozena od třídy CheckBox, přidejte „DataValue“ majetek, který dokáže pracovat s hodnotami DBNULL a svázat data „DataValue“ vlastnost:

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;
            }
        }
    }
}
Odpovězeno 18/08/2009 v 07:58
zdroj uživatelem

hlasů
7

Zkoušeli jste vázání CheckBox.CheckState do DataColumn bez připojení k analyzování a naformátování události nebo si hrát s vazbou?

Bohužel nemám instanci Visual Studio 2005 k dispozici, ale já shromáždil rychlá forma v Visual Studio 2008 a udělal přesně to, co jste zadali:

Jako poznámka: Hodnota DBNull je přijatelné pouze tehdy, pokud pocházejí z DataSet (to znamená, že nikdy nebyla nastavena hodnota). Ale uživatel by měl být schopen nastavit hodnotu True nebo False přes CheckBox pouze.

I může být Parse, formát nebo vazba stále v cestě, nebo to může být, že Windows Forms se chová odlišně v roce 2008 než v roce 2005


UPDATE 18.srpna: Pracuje na Visual Studio 2005 také jak prostřednictvím projektanta a prostřednictvím kódu. Zde je kód, který to dokazuje práci:


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--;
        }
    }
}


UPDATE 23.srpna:

Proč to funguje

Vazba má vlastní metodu nazvanou FormatObject který je zodpovědný za získání reprezentace hodnoty přicházející ze zdroje dat, který je vhodný pro zobrazováno na ovládání.

Je-li povoleno formátování Binding.FormatObject () bude probíhat prostřednictvím kódu cestu, která bude volat případné manipulátory, které máte na akci Binding.Format. Pokud některý psovod změní hodnotu jsou šířeny ze zdroje dat ke kontrole přes ConvertEventArgs.Value, bude použita tato hodnota. V opačném případě bude volat výchozí formátovací s názvem FormatObject na vnitřní třídu s názvem System.Windows.Forms.Formatter.

Připomínky k stavu zdrojového kódu:

„Skutečná přeměna práce se děje uvnitř FormatObjectInternal ()“

Připomínky k FormatObjectInternal stavu:

„Provede některé speciální případ konverze (např. Logická hodnota CheckState)“

Uvnitř FormatObjectInternal zkontroluje, zda je hodnota přicházející ze zdroje dat je null nebo DBNull, a pokud tomu tak je, zkontroluje, zda je typ majetku, který je vázán je CheckState. Pokud tomu tak je, se vrací CheckState.Indeterminate.

Jak vidíte, to je takový běžný případ, že je to překvapení to nefungovalo na Windows Forms 1.x. Naštěstí připevnil ji na 2,0 a dále.

Odpovězeno 18/08/2009 v 11:25
zdroj uživatelem

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