Лучший способ привязать элемент управления Winforms к обнуляемому типу? - PullRequest
18 голосов
/ 18 декабря 2008

В настоящее время я использую привязку данных winforms для подключения формы редактирования данных. Я использую инфраструктуру netTiers через CodeSmith для генерации моих объектов данных. Для полей базы данных, допускающих значения NULL, создаются типы, допускающие значения NULL. Я обнаружил, что при использовании привязки данных winforms элементы управления не будут правильно привязываться к обнуляемым типам.

В Интернете я видел решения, предполагающие, что люди создают новые классы текстовых полей, которые могут обрабатывать обнуляемые типы, но это может быть затруднительно при замене текстовых полей в формах, которые я уже создал.

Изначально я думал, что было бы здорово использовать метод расширения для этого. По сути, создаем свойство расширения для класса текстового поля и привязываем к нему. Из моего опыта работы с ограниченным методом расширения и небольшой проверки он-лайн кажется, что вы не можете использовать свойство расширения. Насколько я могу судить, привязка должна осуществляться через свойство, поскольку оно должно иметь возможность получить или установить значение, чтобы метод расширения не работал.

Я бы хотел найти чистый способ модификации этих форм, используя что-то вроде методов расширения, но если мне придется создавать новые элементы управления textbox и combo box, это то, что я сделаю.

Мой проект в настоящее время ограничен .Net 2.0 из-за необходимости запуска в Windows 2000.

Есть предложения?

Ответы [ 4 ]

42 голосов
/ 19 августа 2010

В разделе комментариев статьи, на которую ссылаются выше, один из плакатов предлагает простое решение.

Вместо связывания с:

textBox1.DataBindings.Add("Text", myClass, "MyTextProperty");

Свяжите с:

textBox1.DataBindings.Add("Text", myClass, "MyTextProperty", true, DataSourceUpdateMode.OnPropertyChanged, string.Empty); 
5 голосов
/ 05 февраля 2009

Я только что наткнулся на эту проблему сам, и это настоящая головная боль.

Самое смешное в связывании типов, допускающих значения NULL, заключается в том, что DataGridView обрабатывает их без каких-либо проблем - только текстовые поля вызывают проблемы.

Это довольно неприятно - даже кажется, что оно не позволяет закрыть форму, когда у вас есть пустое значение в текстовом поле, и кажется, что вы также не можете уйти от него.

Итак, это не очень хороший ответ, но я предлагаю попробовать придерживаться таблиц данных для типов Nullable в форме.

Другим предложением является использование «поставщика расширителей», как предлагается здесь, хотя я еще не тестировал его:

РЕДАКТИРОВАТЬ: Теперь скачали образец кода на этой странице, и он работает ЯРКО.

http://www.thejoyofcode.com/Databinding_and_Nullable_types_in_WinForms.NET.aspx

1 голос
/ 18 декабря 2008

Ох, противно ... Я могу придумать только пару способов добиться этого, и ни один из них я бы не назвал идеальным.

  • Первый - написать оболочку для вашего объекта данных, содержащую обнуляемые значения, которые преобразуют все обнуляемые значения в пустые строки. Привязать к объекту-оболочке.

  • Во-вторых, убедитесь, что все значения в вашей базе данных не равны нулю ... опять же, не идеальны

  • Третье, что вы уже решили, что в этой ситуации не жизнеспособно, - это создание пользовательского объекта, расширяющего текстовое поле для добавления свойства, которое может связываться с обнуляемым значением.

  • Четвертый самый идеальный способ, который я мог придумать, не представляется возможным. Создайте свойство расширения, которое позволит вам расширять все объекты текстового поля и связываться с ним, но не представляется возможным, чтобы в это время были доступны свойства расширения. Похоже, что это ситуация, когда этот тип функций будет особенно полезен в .NET Framework.

0 голосов
/ 27 декабря 2018

С Связывание данных и типы Nullable в WinForms.NET

Сценарий

  • У вас есть тип сущности со свойством Nullable.
  • У вас есть TextBox, который связан с этим свойством.
  • Когда пользователь очищает текст в TextBox, вы хотите, чтобы значение вашего свойства было установлено равным нулю.

Задача

Результат привязки данных просто не будет успешным при очистке TextBox, который связан с типом Nullable.

Решение

В этой статье я собираюсь показать, как вы можете сделать это с помощью Extender Provider.

Просто добавьте класс Component в ваш проект, который также реализует интерфейс IExtenderProvider

[ProvideProperty("NullableBinding", typeof(TextBox))]  
public partial class NullableExtender : Component, IExtenderProvider

Атрибут ProviderProperty указывает, что при добавлении компонента NullableExtender в вашу форму или UserControl все текстовые поля будут иметь дополнительное свойство с именем NullableBinding. В конструкторе VS.NET это будет выглядеть примерно так:

NullableBinding Property

Теперь, чтобы реализовать некоторые функции для этого свойства:

private Dictionary<Control, Boolean> _nullables = new Dictionary<Control,bool>();

/// <summary>
/// This is the get part of the extender property.
/// It is actually a method because it takes the control.
/// </summary>
/// <param name="control"></param>
[DefaultValue(false),
Category("Data")]
public bool GetNullableBinding(Control control)
{
    bool nullableBinding = false;
    _nullables.TryGetValue(control, out nullableBinding);
    return nullableBinding;
}

/// <summary>
/// This is the set part of the extender property.
/// It is actually a method because it takes the control.
/// </summary>
/// <param name="control"></param>
/// <param name="nullable"></param>
public void SetNullableBinding(Control control, bool nullable)
{
    if (_nullables.ContainsKey(control))
        _nullables[control] = nullable;
    else
        _nullables.Add(control, nullable);
    if (nullable)
    {
        // Add a parse event handler.
        control.DataBindings["Text"].Parse += new ConvertEventHandler(NullableExtender_Parse);
    }
}

/// <summary>
/// When parsing, set the value to null if the value is empty.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void NullableExtender_Parse(object sender, ConvertEventArgs e)
{
    if (e.Value.ToString().Length == 0)
    {
        e.Value = null;
    }
}

Код, который на самом деле выполняет вышеприведенный трюк, добавляет обработчик события для события Parse привязки данных. Обработчик событий просто устанавливает значение null, если значение представляет собой пустую строку, и привязка данных завершается успешно.

Значение свойства по умолчанию установлено в false, так как большинство свойств не имеют типа Nullable, и я бы предложил не устанавливать для NullableBinding значение true для этих свойств ...;)

...