我有一个RadDatePicker
。以下代码中的NoDotRadDatePicker
继承自RadDateTimePicker
当我从控件中选择一个日期时,它将按预期工作并更新view属性。但是,当我编辑与选择器关联的文本框时,它不会对模型进行任何更改。
试图将UpdateSourceTrigger
更改为propertychange
,但没有帮助
<controls:NoDotRadDatePicker Grid.Row="0" HorizontalAlignment="Left"
Grid.Column="1" MaxWidth="120"
SelectedValue="{Binding Path=ValidFrom, ValidatesOnDataErrors=True, UpdateSourceTrigger=Default, Mode=TwoWay}"
Style="{StaticResource NoDotDatePickerRightWatermarkContent}" />
public class NoDotRadDatePicker : RadDateTimePicker
{
public NoDotRadDatePicker()
{
this.InputMode = InputMode.DatePicker;
this.ParseDateTimeValue += RadDateTimePicker_OnParseDateTimeValue;
this.Culture = new CultureInfo("de-DE");
this.Culture.DateTimeFormat.ShortDatePattern = "dd.MM.yyyy";
this.Culture.DateTimeFormat.DateSeparator = ".";
this.Loaded += NoDotRadDatePicker_Loaded;
}
private void RadDateTimePicker_OnParseDateTimeValue(object sender, ParseDateTimeEventArgs args)
{
const int firstDayInMonth = 1;
const int firstMonth = 1;
string input = args.TextToParse.ToLower();
if (!ContainsOnlyDigitsAndDot(input))
{
args.IsParsingSuccessful = false;
return;
}
int day = firstDayInMonth;
int month = firstMonth;
int year = DateTime.Now.Year;
if (!SplitDateTime2Parts(input, ref day, ref month, ref year))
{
args.IsParsingSuccessful = false;
return;
}
args.Result = new DateTime(year, month, day);
args.IsParsingSuccessful = true;
}
private bool SplitDateTime2Parts(string input, ref int day, ref int month, ref int year)
{
int k = 0;
var partOfYearCounter = DateTimeParts.Day;
string parsePart = "";
foreach (char t in input)
{
if (t == '.')
{
if (string.IsNullOrEmpty(parsePart)) continue;
if (!DoTheDayMonthParsing(ref k, ref parsePart, ref day, ref month, ref partOfYearCounter)) return false;
continue;
}
parsePart += t;
k++;
if (k != 2 || (partOfYearCounter != DateTimeParts.Day && partOfYearCounter != DateTimeParts.Month)) continue;
if (!DoTheDayMonthParsing(ref k, ref parsePart, ref day, ref month, ref partOfYearCounter)) return false;
}
if (partOfYearCounter == DateTimeParts.Day || partOfYearCounter == DateTimeParts.Month)
if (!ParseDayOrMonthHelper(partOfYearCounter, parsePart, ref day, ref month)) return false;
if (partOfYearCounter == DateTimeParts.Year)
if (!DoTheYearParsing(parsePart, ref year)) return false;
if (day > DateTime.DaysInMonth(year, month)) return false;
return true;
}
private bool DoTheYearParsing(string parsePart, ref int year)
{
if (string.IsNullOrEmpty(parsePart)) return true;
int parsedYear;
if (!int.TryParse(parsePart, out parsedYear)) return false;
year = parsedYear;
if (year >= 0 && year <= 49) year += 2000;
if (year >= 50 && year <= 99) year += 1900;
if (year < 1753 || year > 3000) return false;
return true;
}
private bool DoTheDayMonthParsing(ref int k,
ref string parsePart, ref int day, ref int month,
ref DateTimeParts partOfYearCounter)
{
if (!ParseDayOrMonthHelper(partOfYearCounter, parsePart, ref day, ref month))
return false;
if (partOfYearCounter == DateTimeParts.Month) partOfYearCounter = DateTimeParts.Year;
if (partOfYearCounter == DateTimeParts.Day) partOfYearCounter = DateTimeParts.Month;
parsePart = "";
k = 0;
return true;
}
private bool ParseDayOrMonthHelper(DateTimeParts partOfYearCounter, string parsePart, ref int day, ref int month)
{
if (string.IsNullOrEmpty(parsePart)) return true;
switch (partOfYearCounter)
{
case DateTimeParts.Day:
if (!ParseValueHelper(parsePart, ref day, 1, 31)) return false;
break;
case DateTimeParts.Month:
if (!ParseValueHelper(parsePart, ref month, 1, 12)) return false;
break;
default:
return false;
}
return true;
}
private bool ParseValueHelper(string parsePart, ref int value2StoreIn, int lowBoundary, int highBoundary)
{
int parsedValue;
if (!int.TryParse(parsePart, out parsedValue)) return false;
if (parsedValue == 0) return true;
if (parsedValue >= lowBoundary && parsedValue <= highBoundary)
{
value2StoreIn = parsedValue;
return true;
}
return false;
}
private bool ContainsOnlyDigitsAndDot(string string2BeChecked)
{
return string2BeChecked.All(t => char.IsDigit(t) || t == '.');
}
enum DateTimeParts
{
Day = 1,
Month = 2,
Year = 3
};
void NoDotRadDatePicker_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
if (this.VisualChildrenCount == 0)
return;
var rootElement = VisualTreeHelper.GetChild(sender as RadDateTimePicker, 0) as FrameworkElement;
RadWatermarkTextBox watermarkTextBlock = (RadWatermarkTextBox)rootElement.FindName("PART_DateTimeInput");
var contentControl = watermarkTextBlock.ChildrenOfType<ContentControl>().Where(p => p.Name == "WatermarkVisualElement").First();
if (contentControl != null)
{
contentControl.Opacity = 1.0;
contentControl.Foreground = new SolidColorBrush(Colors.Black);
//contentControl.FontStyle = FontStyles.Normal;
}
}
}