Come associare un CheckBox a un bool digitato DBColumn che è annullabile?

voti
4

In Windows Form (.NET 2.0, Visual Studio 2005 SP1): Ho un tipizzato DataSet, con una colonna, che tipo è System.Boolean, che è nullable, e che il valore predefinito è DBNull. Ho un Form, che contiene un CheckBoxcontrollo che voglio associare al valore della colonna precedente.

  • Ho cercato di impegnare la Checkedproprietà per la colonna tramite il designer: funziona benissimo, solo se il valore predefinito per la colonna è impostata su Trueo False.
  • Ho cercato di impegnare la CheckStateproprietà per la colonna tramite il progettista, e allegando le mie Formate Parsegestori di eventi, ma non ottengono mai chiamato:

    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
    };
    
  • Ho cercato di creare un costume Bindingesempio nel codice, collegare i miei gestori di eventi e aggiungerlo agli CheckBoxattacchi: i gestori di eventi sono ancora mai vengono chiamati ...

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

Come nota: un DBNullvalore accettabile solo quando proveniente dal DataSet(significa il valore non è mai stato impostato). Ma l'utente dovrebbe essere solo in grado di impostare il valore Trueo Falsetramite il CheckBox.

Per riferimento, ecco il codice dei metodi di analisi e di formattazione:

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;
}
È pubblicato 13/08/2009 alle 14:52
fonte dall'utente
In altre lingue...                            


2 risposte

voti
1

Il modo in cui easist Lo so, è derivare da classe CheckBox, aggiungere proprietà "DataValue", che può gestire i valori DBNull e associare i dati alla proprietà "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;
            }
        }
    }
}
Risposto il 18/08/2009 a 07:58
fonte dall'utente

voti
7

Hai provato vincolante CheckBox.CheckState al DataColumn senza associare per analizzare e gli eventi Format o scherzi con il vincolante?

Purtroppo non ho un'istanza di Visual Studio 2005 disponibili, ma ho assemblato un rapido form in Visual Studio 2008 e lo ha fatto esattamente quello che è stato specificato:

Come nota: un valore DBNull è accettabile solo quando proveniente dal DataSet (significa che il valore non è mai stato impostato). Ma l'utente dovrebbe essere solo in grado di impostare il valore su True o False tramite casella di controllo.

Posso essere il Parse, Formato o Binding ottenere nel vostro modo o può essere che si comporta in modo diverso Windows Form nel 2008 rispetto al 2005


AGGIORNAMENTO 18 AGOSTO: Funziona su Visual Studio 2005 troppo sia attraverso il progettista e tramite il codice. Ecco il codice che dimostra che funziona:


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


AGGIORNAMENTO 23 AGOSTO:

Perché funziona

Legame ha un metodo privato chiamato FormatObject che è responsabile per ottenere una rappresentazione del valore proveniente dalla sorgente dati appropriato per essere mostrato sul controllo.

Quando la formattazione è attivata, Binding.FormatObject () verrà eseguito attraverso un percorso di codice che chiamerà eventuali gestori che avete per l'evento Binding.Format. Se qualsiasi conduttore cambia il valore la propagazione dalla sorgente dati al controllo attraverso ConvertEventArgs.Value, verrà utilizzato quel valore. In caso contrario, sarà chiamare un formattatore predefinito chiamato FormatObject su una classe interno chiamato System.Windows.Forms.Formatter.

I commenti sullo stato del codice sorgente:

“Il vero lavoro conversione avviene all'interno FormatObjectInternal ()”

I commenti per lo stato FormatObjectInternal:

“Esegue alcune conversioni casi speciali (ad es. Booleana per CheckState)”

All'interno di FormatObjectInternal viene verificato se il valore proveniente dalla sorgente dati è nullo o DBNull e se questo è il caso, viene verificato se il tipo di proprietà di essere vincolato è CheckState. Se questo è il caso, restituisce CheckState.Indeterminate.

Come si può vedere, questo è un caso così comune che si tratta di una sorpresa che non ha funzionato su Windows Form 1.x. Per fortuna, il fisso su 2.0 e oltre.

Risposto il 18/08/2009 a 11:25
fonte dall'utente

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