2016-04-22 2 views
2

У меня есть следующий класс:Как использовать выражение лямбда для обновления свойства?

public class MyClass 
{ 
    public int? Field1 { get; set; } 
    public int? Field2 { get; set; } 
} 

Элементы управление TextBox на форме привязаны к экземпляру этого класса через BindingSource, а источник данных является обновлением на OnValidated событии.

Однако, когда текстовое поле пусто, то свойство это обязательно не обновляется (предыдущее значение отображается снова):

Так, на OnValidating случае на блок управления я добавил следующее:

int value; 
bool ok = int.TryParse(((TextBox)sender).Text, out value); 
if (!ok) 
{ 
    myClassInstance.Field1 = null; 
} 

Вопросы:

  1. Является ли выше нормального поведения BindingSource, когда значение TextBox пуст?

  2. Возможно ли иметь общий метод, который я могу вызвать в своих OnValidating событиях. Что-то вроде:

    OnValidatingMethod((TextBox)sender, x => x.Field1); 
    

выше строка кода, очевидно, не работает, так как экземпляр объекта не ссылается. Но мне было интересно, возможно ли что-то подобное? Возможно, расширение для класса:

myClassInstance.SetProperty(((TextBox)sender).Text, x => x.Field1); 

ответ

1

Вся идея привязки данных заключается в абстрагировании цели от источника. Если вы создадите такие обработчики событий, абстракция закончится.

То, что вы видите, конечно, не нормально, но это результат очень старых ошибок, сохраненных для «обратной совместимости». Он был исправлен давно, добавив дополнительные свойства в класс Binding, но опять же для обратной совместимости значения по умолчанию настроены так, чтобы имитировать старое поведение.

Свойства, которые необходимо установить, чтобы заставить его работать, как ожидается, являются FormattingEnabled к true и NullValue к "". Я обычно использую один из DataBindings.Add или Binding конструктора перегрузок, что позволяет указать всю эту информацию, как это:

textBox.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, ""); 

Вот полный дем:

using System; 
using System.Windows.Forms; 

namespace Samples 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      var form = new Form(); 
      var textBox1 = new TextBox { Parent = form, Left = 16, Top = 16 }; 
      var textBox2 = new TextBox { Parent = form, Left = 16, Top = textBox1.Bottom + 16 }; 
      var bs = new BindingSource { DataSource = typeof(MyClass) }; 
      textBox1.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, ""); 
      textBox2.DataBindings.Add("Text", bs, "Field2", true, DataSourceUpdateMode.OnValidation, ""); 
      bs.DataSource = new MyClass { Field1 = 1, Field2 = 2 }; 
      Application.Run(form); 
     } 
    } 

    public class MyClass 
    { 
     public int? Field1 { get; set; } 
     public int? Field2 { get; set; } 
    } 
} 

Наконец, если вы действительно хотите принять участие в парсинговой части вы должны приложить обработчик к событию Binding.Parse.

+1

Спасибо за объяснение и, как обычно, отличный ответ! –

Смежные вопросы