Я предлагаю использовать конвертер для достижения того, что вы хотите.
XAML вашего пользовательского элемента управления будет выглядеть следующим образом:
<UserControl x:Class="MyDateControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:MyDateControl"
x:Name="root">
<UserControl.Resources>
<my:DatePartConverter x:Key="DatePartConverter"
Date="{Binding ElementName=root, Path=Date}"/>
</UserControl.Resources>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox Name="textbox_year" Text="{Binding ElementName=root, Path=Date, Converter={StaticResource DatePartConverter}, ConverterParameter=year, Mode=TwoWay}"/>
<TextBox Name="textbox_month" Text="{Binding ElementName=root, Path=Date, Converter={StaticResource DatePartConverter}, ConverterParameter=month, Mode=TwoWay}" />
<TextBox Name="textbox_day" Text="{Binding ElementName=root, Path=Date, Converter={StaticResource DatePartConverter}, ConverterParameter=day, Mode=TwoWay}" />
</StackPanel>
</StackPanel>
</UserControl>
В программном коде у вас будет только свойство зависимости:
public DateTime Date {
get { return (DateTime)GetValue(DateProperty); }
set { SetValue(DateProperty, value); }
}
public static readonly DependencyProperty DateProperty =
DependencyProperty.Register("Date", typeof(DateTime), typeof(MyDateControl),
new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
И конвертер будет выглядетькак то так:
public class DatePartConverter : Freezable, IValueConverter
{
public DateTime Date {
get { return (DateTime)GetValue(DateProperty); }
set { SetValue(DateProperty, value); }
}
public static readonly DependencyProperty DateProperty =
DependencyProperty.Register("Date", typeof(DateTime), typeof(DatePartConverter), new UIPropertyMetadata(DateTime.Now));
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
DateTime date = (DateTime)value;
string datePartType = (string)parameter;
string result;
switch (datePartType) {
case "year":
result = date.Year.ToString().PadLeft(4, '0');
break;
case "month":
result = date.Month.ToString().PadLeft(2, '0');
break;
case "day":
result = date.Day.ToString().PadLeft(2, '0');
break;
default:
throw new InvalidOperationException("Unknown date part type (ConverterParameter)");
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
string datePartValue = (string)value;
string datePartType = (string)parameter;
DateTime result;
switch (datePartType) {
case "year":
result = new DateTime(int.Parse(datePartValue), Date.Month, Date.Day);
break;
case "month":
result = new DateTime(Date.Year, int.Parse(datePartValue), Date.Day);
break;
case "day":
result = new DateTime(Date.Year, Date.Month, int.Parse(datePartValue));
break;
default:
throw new InvalidOperationException("Unknown date part type (ConverterParameter)");
}
return result;
}
protected override Freezable CreateInstanceCore() {
return new DatePartConverter();
}
}