Jak powiązać pole wyboru, aby bool wpisany DbColumn że jest pustych?

głosy
4

W Windows Forms (.NET 2.0, Visual Studio 2005 SP1): mam wpisane DataSet, z kolumny, która jest typ System.Boolean, który jest pustych i których wartość domyślna to DBNull. Mam Form, zawierające CheckBoxkontrolę że ma wiązać się z uprzednią wartość kolumny.

  • Starałem się powiązać Checkedobiekt do kolumny poprzez autora: działa świetnie, tylko wtedy, gdy wartość domyślna jest ustawiona na kolumnie albo Truealbo False.
  • Starałem się wiązać CheckStatewłaściwość kolumny przez projektanta, a dołączenie własnych Formati Parseobsługi zdarzeń, ale nigdy się nie nazywa się:

    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
    };
    
  • Próbowałem utworzyć niestandardową Bindinginstancję w kodzie, należy dołączyć moje obsługi zdarzeń i dodać go do CheckBoxwiązania: obsługi zdarzeń nigdy nie są jeszcze sprawdzony ...

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

Na marginesie: a DBNullwartość jest dopuszczalne tylko wtedy, gdy pochodzący z DataSet(to znaczy wartość nie została ustawiona). Ale użytkownik powinien być w stanie ustawić wartość jedynie Truelub Falseza pośrednictwem CheckBox.

Dla porównania, tutaj jest kod z metod analizowania i formatowania:

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;
}
Utwórz 13/08/2009 o 14:52
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
1

Easist sposób wiem, czy wywodzą się z klasy CheckBox, dodać „danych typu” nieruchomości, które może obsługiwać wartości DBNull i powiązać dane do „danych typu” właściwość:

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;
            }
        }
    }
}
Odpowiedział 18/08/2009 o 07:58
źródło użytkownik

głosy
7

Czy próbowałeś wiążące CheckBox.CheckState do DataColumn bez dołączania do analizowania i wydarzenia formacie lub brudząc z wiązaniem?

Niestety nie mam instancję Visual Studio 2005 dostępne ale zmontowane szybkie formą w Visual Studio 2008 i zrobił dokładnie to, co podałeś:

Jako Uwaga: wartość DBNull jest dopuszczalne tylko wtedy, gdy pochodzą z zestawu danych (oznacza to, że wartość nie została ustawiona). Ale użytkownik powinien być w stanie ustawić wartość Prawda czy fałsz poprzez CheckBox tylko.

Mogę być Parse, Format lub wiążących się w sposób lub może być tak, że Windows Forms zachowuje się inaczej w 2008 roku niż w 2005 roku


AKTUALIZACJA 18 sierpnia: To działa na Visual Studio 2005 za oba przez projektanta i poprzez kod. Oto kod, który demonstruje to działa:


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


AKTUALIZACJA 23 sierpnia:

Dlaczego to działa

Wiązanie ma prywatną metodę zwaną FormatObject który jest odpowiedzialny za uzyskanie reprezentacji wartości pochodzące ze źródła danych, które są odpowiednie dla pokazano na kontrolę.

Podczas formatowania jest włączona, Binding.FormatObject () będzie prowadzony przez ścieżki kodu, który nazywamy ewentualnych teleskopowe masz na razie Binding.Format. Jeżeli którykolwiek obsługi zmienia wartość propagowany ze źródła danych do kontroli przez ConvertEventArgs.Value, które zostaną wykorzystane wartość. W przeciwnym razie będzie to nazwać domyślnego formatowania nazwie FormatObject na klasy wewnętrznym zwanym System.Windows.Forms.Formatter.

Uwagi dotyczące stanu kodu źródłowego:

„Prawdziwa praca konwersja dzieje wewnątrz FormatObjectInternal ()”

Uwagi dotyczące stanu FormatObjectInternal:

„Wykonuje kilka specjalnych przypadków konwersji (np. Boolean do checkState)”

Wewnątrz FormatObjectInternal sprawdza, czy wartość pochodzących ze źródła danych jest zerowy lub DBNull a jeśli tak jest, to sprawdza, czy typ nieruchomości wiążąc jest checkState. Jeśli tak jest, to zwraca CheckState.Indeterminate.

Jak widać, jest to tak powszechne, że sprawa jest zaskoczeniem to nie działa na Windows Forms 1.x. Na szczęście, naprawić go na 2,0 i poza nią.

Odpowiedział 18/08/2009 o 11:25
źródło użytkownik

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