I have 2 controls:
我有2个控件:
DatePicker: For Date Only
TextBox with TimeMask: For Time Only
DatePicker:仅限日期使用TimeMask的TextBox:仅限时间
They are both linked to the same property DateTime EffectiveDate
But the problem is when I change the Date on the DatePicker, it changes the Time in the TimeTextBox back to 12:00.
它们都链接到同一属性DateTime EffectiveDate但问题是当我更改DatePicker上的Date时,它将TimeTextBox中的Time更改回12:00。
I understand the reason for it, but what best solution is out there to let these work separately but bound to the same property?
我理解它的原因,但是最好的解决方案是让它们分开工作但是绑定到同一个属性?
I have tried to take the current time and build a new Date in the set property but always end up with overflow errors.
我试图占用当前时间并在set属性中构建一个新的Date但总是出现溢出错误。
4 个解决方案
#1
3
You can use a value converter to hold on to the value
您可以使用值转换器来保持该值
public class DateConverter : IValueConverter
{
private DateTime timePickerDate;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
timePickerDate = ((DateTime)(value));
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return timePickerDate;
var datePickerDate = ((DateTime)(value));
// compare relevant parts manually
if (datePickerDate.Hour != timePickerDate.Hour
|| datePickerDate.Minute != timePickerDate.Minute
|| datePickerDate.Second != timePickerDate.Second)
{
// correct the date picker value
var result = new DateTime(datePickerDate.Year,
datePickerDate.Month,
datePickerDate.Day,
timePickerDate.Hour,
timePickerDate.Minute,
timePickerDate.Second);
// return, because this event handler will be executed a second time
return result;
}
return datePickerDate;
}
}
And have the two controls in question bind to the one property but have the date picker use the converter to not override the time.
并且有问题的两个控件绑定到一个属性,但让日期选择器使用转换器不覆盖时间。
<Grid Margin="10,5" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<sdk:DatePicker Grid.Column="0" TabIndex="1" Padding="0" SelectedDate="{Binding EffectiveDate, Mode=TwoWay, Converter={StaticResource DateConverter}}" SelectedDateFormat="Short"/>
<toolkit:TimePicker Grid.Column="1" Value="{Binding EffectiveDate, Mode=TwoWay}" Margin="0" Padding="0" HorizontalAlignment="Left" TabIndex="2" />
</Grid>
#2
3
You could do something like this:
你可以这样做:
private DateTime _effectiveDate;
...
public DateTime DateOfEffectiveDate
{
get { return _effectiveDate; }
set
{
_effectiveDate = new DateTime(value.Year, value.Month, value.Day, _effectiveDate.Hour, _effectiveDate.Minute, _effectiveDate.Second);
}
}
public DateTime TimeOfEffectiveDate
{
get { return _effectiveDate; }
set
{
_effectiveDate = new DateTime(_effectiveDate.Year, _effectiveDate.Month, _effectiveDate.Day, value.Hour, value.Minute, value.Second);
}
}
#3
1
The built-in DatePicker control selects only a date without any specific time so I am afraid it makes no sense to try to display the time of the selected date in a TextBox. The DatePicker will effectively clear out the time part each time a new date is selected. This is how the control works.
内置的DatePicker控件只选择没有任何特定时间的日期,所以我担心尝试在TextBox中显示所选日期的时间是没有意义的。每次选择新日期时,DatePicker将有效清除时间部分。这就是控件的工作原理。
So you should bind the DatePicker and the TextBox to two different source properties, a DateTime?
and a TimeSpan
respectively.
那么你应该将DatePicker和TextBox绑定到两个不同的源属性,一个DateTime?和一个TimeSpan分别。
The other option would be to use another control that selects a date and a time, for example this one: http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker
另一种选择是使用另一个选择日期和时间的控件,例如:http://wpftoolkit.codeplex.com/wikipage?title = DateTimePicker
#4
0
Catch dateTimePicker1_ValueChanged
event and then set binded field value
combining date
and time
parts
捕获dateTimePicker1_ValueChanged事件,然后设置合并日期和时间部分的绑定字段值
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
DateTime dt = dateTimePicker1.Value;
int hour = Convert.ToInt32(textBox1.Text.Split(':')[0]);
int minute = Convert.ToInt32(textBox1.Text.Split(':')[1]);
bindedfield = new DateTime(dt.Year, dt.Month, dt.Day, hour, minute, 0);
}
#1
3
You can use a value converter to hold on to the value
您可以使用值转换器来保持该值
public class DateConverter : IValueConverter
{
private DateTime timePickerDate;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
timePickerDate = ((DateTime)(value));
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return timePickerDate;
var datePickerDate = ((DateTime)(value));
// compare relevant parts manually
if (datePickerDate.Hour != timePickerDate.Hour
|| datePickerDate.Minute != timePickerDate.Minute
|| datePickerDate.Second != timePickerDate.Second)
{
// correct the date picker value
var result = new DateTime(datePickerDate.Year,
datePickerDate.Month,
datePickerDate.Day,
timePickerDate.Hour,
timePickerDate.Minute,
timePickerDate.Second);
// return, because this event handler will be executed a second time
return result;
}
return datePickerDate;
}
}
And have the two controls in question bind to the one property but have the date picker use the converter to not override the time.
并且有问题的两个控件绑定到一个属性,但让日期选择器使用转换器不覆盖时间。
<Grid Margin="10,5" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<sdk:DatePicker Grid.Column="0" TabIndex="1" Padding="0" SelectedDate="{Binding EffectiveDate, Mode=TwoWay, Converter={StaticResource DateConverter}}" SelectedDateFormat="Short"/>
<toolkit:TimePicker Grid.Column="1" Value="{Binding EffectiveDate, Mode=TwoWay}" Margin="0" Padding="0" HorizontalAlignment="Left" TabIndex="2" />
</Grid>
#2
3
You could do something like this:
你可以这样做:
private DateTime _effectiveDate;
...
public DateTime DateOfEffectiveDate
{
get { return _effectiveDate; }
set
{
_effectiveDate = new DateTime(value.Year, value.Month, value.Day, _effectiveDate.Hour, _effectiveDate.Minute, _effectiveDate.Second);
}
}
public DateTime TimeOfEffectiveDate
{
get { return _effectiveDate; }
set
{
_effectiveDate = new DateTime(_effectiveDate.Year, _effectiveDate.Month, _effectiveDate.Day, value.Hour, value.Minute, value.Second);
}
}
#3
1
The built-in DatePicker control selects only a date without any specific time so I am afraid it makes no sense to try to display the time of the selected date in a TextBox. The DatePicker will effectively clear out the time part each time a new date is selected. This is how the control works.
内置的DatePicker控件只选择没有任何特定时间的日期,所以我担心尝试在TextBox中显示所选日期的时间是没有意义的。每次选择新日期时,DatePicker将有效清除时间部分。这就是控件的工作原理。
So you should bind the DatePicker and the TextBox to two different source properties, a DateTime?
and a TimeSpan
respectively.
那么你应该将DatePicker和TextBox绑定到两个不同的源属性,一个DateTime?和一个TimeSpan分别。
The other option would be to use another control that selects a date and a time, for example this one: http://wpftoolkit.codeplex.com/wikipage?title=DateTimePicker
另一种选择是使用另一个选择日期和时间的控件,例如:http://wpftoolkit.codeplex.com/wikipage?title = DateTimePicker
#4
0
Catch dateTimePicker1_ValueChanged
event and then set binded field value
combining date
and time
parts
捕获dateTimePicker1_ValueChanged事件,然后设置合并日期和时间部分的绑定字段值
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
DateTime dt = dateTimePicker1.Value;
int hour = Convert.ToInt32(textBox1.Text.Split(':')[0]);
int minute = Convert.ToInt32(textBox1.Text.Split(':')[1]);
bindedfield = new DateTime(dt.Year, dt.Month, dt.Day, hour, minute, 0);
}