.Net DataBinding новый объект со свойствами типа значения - PullRequest
2 голосов
/ 24 октября 2008

Используя привязку данных, как связать новый объект, который использует типы значений?

Простой пример:

public class Person() {
    private string _firstName;
    private DateTime _birthdate;
    private int _favoriteNumber;
    //Properties
}

Если я создам новый Person () и привяжу его к форме с текстовыми полями. Дата рождения отображается как 01/01/0001, а любимый номер - как 0. Эти поля обязательны для заполнения, но я бы хотел, чтобы эти поля были пустыми и чтобы пользователь заполнил их.

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

Я специально спрашиваю о Silverlight, но предполагаю, что WPF и WinForms, вероятно, имеют одну и ту же проблему.

EDIT:

Я думал о типах Nullable, однако в настоящее время мы используем одни и те же доменные объекты на клиенте и сервере, и я не хочу, чтобы обязательные поля были Nullable. Я надеюсь, что механизм привязки данных предоставляет способ узнать, связывает ли он новый объект?

Ответы [ 5 ]

2 голосов
/ 24 октября 2008

Возможно, вы можете попробовать Nullable типы?

public class Person() {
    private string? _firstName;
    private DateTime? _birthdate;
    private int? _favoriteNumber;
    //Properties
}

или

public class Person() {
    private Nullable<string> _firstName;
    private Nullable<DateTime> _birthdate;
    private Nullable<int> _favoriteNumber;
    //Properties
}

что на самом деле то же самое.

Теперь значения по умолчанию равны нулю, и вы можете задать для свойств значение, установив их.

Подробнее о типах Nullable:

http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

1 голос
/ 26 октября 2008

Попробуйте использовать конвертер значений, вот пример, с которого следует начать.

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

public class DefaultValueToNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        object result = value;
        Type valueType = parameter as Type;

        if (value != null && valueType != null && value.Equals(defautValue(valueType)))
        {
            result = null;
        }

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        object result = value;
        Type valueType = parameter as Type;

        if (value == null && valueType != null )
        {
            result = defautValue(valueType);
        }
        return result;
    }

    private object defautValue(Type type)
    {
        object result = null;
        if (type == typeof(int))
        {
            result = 0;
        }
        else if (type == typeof(DateTime))
        {
            result = DateTime.MinValue;
        }
        return result;
    }
}

Тогда в вашем справочнике xaml такой конвертер

<Page.Resources>
    <local:DefaultValueToNullConverter x:Key="DefaultValueToNullConverter"/>
</Page.Resources>

<TextBox 
    Text="{Binding 
            Path=BirthDate, 
            Converter={StaticResource DefaultValueToNullConverter},
            ConverterParameter={x:Type sys:DateTime}}" 
    />
0 голосов
/ 28 октября 2008

После того, как конвертер установлен, вам также необходимо включить INotifyPropertyChanged в объект Person. Таким образом, вы можете установить привязку Mode = TwoWay для двухсторонней привязки данных, которая будет обновлять значение в объекте, когда в текстовое поле вносятся изменения, а также в vis.

0 голосов
/ 26 октября 2008

Вы можете использовать IValueConverter для форматирования привязок вашего текстового поля к значениям по умолчанию на основе значения объекта. Вот несколько ссылок на IValueConverter

http://ascendedguard.com/2007/08/data-binding-with-value-converters.html http://weblogs.asp.net/marianor/archive/2007/09/18/using-ivalueconverter-to-format-binding-values-in-wpf.aspx

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

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

Вы можете сделать это, имея объект Person.Empty для значений по умолчанию. Или устанавливая эти значения явно, когда установлен DataContext.

В любом случае должно работать:)

0 голосов
/ 26 октября 2008

Я бы переписал класс Person, чтобы он выглядел примерно так ...

public class Person
  {
    private int _favoriteNumber = 0;
    public string FavoriteNumber
    {
      get
      {
        return _favoriteNumber > 0 ? _favoriteNumber.ToString() : string.Empty;
      }
      set
      {
        _favoriteNumber = Convert.ToInt32(value);
      }
    }

    private DateTime _birthDate = DateTime.MinValue;
    private string BirthDate 
    {
      get
      {
        return _birthDate == DateTime.MinValue ? string.Empty : _birthDate.ToString(); //or _birthDate.ToShortDateString() etc etc
      }
      set
      {
        _birthDate = DateTime.Parse(value);
      }
    }
  }
...