Как связать новый объект, использующий типы значений, с помощью привязки данных?
Простой пример:
public class Person() {
private string _firstName;
private DateTime _birthdate;
private int _favoriteNumber;
//Properties
}
Если я создам новый Person () и привяжу его к форме с текстовыми полями. Дата рождения отображается как 01/01/0001, а любимый номер - как 0. Эти поля обязательны, но я бы хотел, чтобы эти поля были пустыми и пользователь их заполнил.
Решение также должно иметь возможность использовать поля по умолчанию. В нашем примере я могу захотеть, чтобы Любимое число по умолчанию было 42.
Я специально спрашиваю о Silverlight, но полагаю, что у WPF и WinForms, вероятно, такая же проблема.
Обновлено:
Я думал о типах, допускающих значение NULL, однако в настоящее время мы используем одни и те же объекты домена на клиенте и сервере, и я не хочу, чтобы обязательные поля имели значение Nullable. Я надеюсь, что механизм привязки данных предоставит способ узнать, что он связывает новый объект?





Возможно, вы можете попробовать типы, допускающие значение NULL?
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
}
что на самом деле то же самое.
Теперь значения по умолчанию равны нулю, и вы можете заставить свойства иметь значение, установив их.
Подробнее о типах, допускающих значение NULL:
Я бы переписал класс 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);
}
}
}
Вы можете использовать IValueConverter для форматирования привязок текстовых полей к значениям по умолчанию на основе значения объекта. Вот несколько ссылок на IValueConverter
http://ascealedguard.com/2007/08/data-binding-with-value-converters.htmlhttp://weblogs.asp.net/marianor/archive/2007/09/18/using-ivalueconverter-to-format-binding-values-in-wpf.aspx
К сожалению, это может быть не то, что вам нужно, поскольку у вас нет опции значения Nullable для каждого из этих свойств.
Что вы можете сделать, так это установить свойства по умолчанию для вашего объекта при выполнении привязки данных.
Вы можете сделать это, имея объект Person.Empty для значений по умолчанию. Или установить эти значения явно, когда установлен DataContext.
В любом случае должно работать :)
Попробуйте использовать преобразователь значений, вот пример, который должен вам помочь.
Основная идея состоит в том, чтобы преобразовать значение по умолчанию для типа в значение NULL при отображении данных и преобразовать любые значения 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}}"
/>
После того, как у вас есть преобразователь, вам также необходимо внедрить INotifyPropertyChanged в объект Person. Таким образом, вы можете установить привязку Mode = TwoWay, двусторонняя привязка данных будет обновлять значение в объекте, когда в текстовом поле вносятся изменения, и в зависимости от вида.