Cum de a lega o casetă de selectare a unui bool tastat DbColumn care permite NULL?

voturi
4

În Windows Forms (.NET 2.0, Visual Studio 2005 SP1): Am un tastat DataSet, cu o coloană , care este de tip System.Boolean, care poate să fie nulă și care este valoarea implicită DBNull. Am Form, care conține un CheckBoxcontrol care doresc să se lege la valoarea din coloana anterioară.

  • Am încercat să lega Checkedproprietatea de a coloanei prin proiectant: it works mare, numai în cazul în care valoarea implicită pentru coloana este setat la Truesau False.
  • Am încercat să lega CheckStateproprietatea de a coloanei prin intermediul proiectantul, și atașarea propriile mele Formatși Parseevenimente stivuitoare , dar niciodată nu se vor numit:

    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
    };
    
  • Am încercat să creeze un obicei Bindingexemplu , în codul, atașați manipulare eveniment meu și adăugați - l la CheckBoxlegările: Stivuitoare eveniment nu sunt niciodată încă se numește ...

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

Ca o notă: o DBNullvaloare este acceptabilă numai în cazul în care vine din DataSet(aceasta înseamnă valoarea nu a fost setată). Dar , utilizatorul ar trebui să poată să stabilească valoarea la numai Truesau Falseprin poarta CheckBox.

Pentru referință, aici este codul de formatare și parsare metode:

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;
}
Întrebat 13/08/2009 la 14:52
sursa de către utilizator
În alte limbi...                            


2 răspunsuri

voturi
1

Modul în care easist știu, este provin din clasa CheckBox, se adaugă „DataValue“ proprietate care pot ocupa valorile DBNull și se leagă datele la „DataValue“ proprietate:

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;
            }
        }
    }
}
Publicat 18/08/2009 la 07:58
sursa de către utilizator

voturi
7

Ați încercat legarea CheckBox.CheckState la DataColumn fără a atașa la Analizează și evenimente Format sau încurcați cu Binding?

Din păcate , nu am un exemplu de Visual Studio 2005 disponibile , dar am asamblat o formă rapidă în Visual Studio 2008 și a făcut exact ceea ce ai specificat:

Ca o notă: o valoare DBNull este acceptabilă numai atunci când vine din setul de date (aceasta înseamnă că valoarea nu a fost setată). Dar, utilizatorul ar trebui să poată să stabilească valoarea la Adevărat sau fals prin caseta de selectare numai.

Eu pot fi parsare, format sau legare incomodeze sau poate fi faptul că Windows Forms se comportă diferit în 2008 decât în ​​2005


UPDATE 18 august: Acesta funcționează pe Visual Studio 2005 prea atât prin proiectantul cât și prin cod. Iată codul pe care îl demonstrează de lucru:


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 august:

De ce funcționează

Legare are o metoda privata numita FormatObject, care este responsabil pentru obținerea unei reprezentări a valorii provenind de la sursa de date care este adecvat pentru a fi afișate pe controlul.

Când formatarea este activată, Binding.FormatObject () va rula printr-o cale de cod care va apela eventualele stivuitoare aveți pentru eveniment Binding.Format. În cazul în care orice handler modifică valoarea fiind propagate de la sursa de date pentru controlul prin ConvertEventArgs.Value, această valoare va fi utilizată. În caz contrar, se va apela un formatorului implicit numit FormatObject pe o clasă internă numită System.Windows.Forms.Formatter.

Comentariile cu privire la starea de cod sursă:

„Adevărata lucrare de conversie se întâmplă în interiorul FormatObjectInternal ()“

Comentariile de stat FormatObjectInternal:

„Efectuează unele conversii-caz special (de ex. Boolean la CheckState)“

În interiorul FormatObjectInternal se verifică pentru a vedea dacă valoarea vine de la sursa de date este nulă sau DBNull și dacă este cazul, se verifică dacă tipul de proprietate fiind legat este de CheckState. În cazul în care este cazul, returnează CheckState.Indeterminate.

După cum puteți vedea, acest lucru este un astfel de caz comun, care este o surpriză că nu a lucrat pe Windows Forms 1.x. Din fericire, l fixat pe 2.0 și dincolo.

Publicat 18/08/2009 la 11:25
sursa de către utilizator

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