Reputation: 324
I have 2 classes, DateTime (the framework class) and FriendlyDateTime (somethign that implements I notify property changed.
the class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ToolSuite.Contract.BaseClasses;
namespace foo.WizardElements
{
public class FriendlyDateTime : NotifyPropertyChangedBase
{
public FriendlyDateTime()
{
}
public FriendlyDateTime(DateTime? value)
{
Date = value;
}
public DateTime? Date
{
get
{
if (base._values.ContainsKey("Date"))
return Get<DateTime>("Date");
else
return null;
}
set
{
if (value == null)
{
if (base._values.ContainsKey("Date"))
base._values.Remove("Date");
}
else
Set<DateTime>("Date", value.Value);
base.NotifyPropertyChanged("Date");
base.NotifyPropertyChanged("Hour");
base.NotifyPropertyChanged("Minute");
}
}
public int Hour
{
get { return Date.HasValue ? Date.Value.Hour : 0; }
set
{
if (Hour > 23)
Hour = 23;
var d = Date.HasValue ? Date.Value : DateTime.Now;
Date = new DateTime(d.Year, d.Month, d.Day, value, Minute, 0);
}
}
public int Minute
{
get { return Date.HasValue ? Date.Value.Minute : 0; }
set
{
if (Minute > 59)
Minute = 59;
var d = Date.HasValue ? Date.Value : DateTime.Now;
Date = new DateTime(d.Year, d.Month, d.Day, Hour, value, 0);
}
}
static public implicit operator DateTime?(FriendlyDateTime value)
{
return value.Date;
}
static public implicit operator FriendlyDateTime(DateTime? value)
{
// Note that because RomanNumeral is declared as a struct,
// calling new on the struct merely calls the constructor
// rather than allocating an object on the heap:
return new FriendlyDateTime(value);
}
}
}
the converter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
using ToolSuite.Contract.BaseClasses;
namespace foo.WizardElements
{
[ValueConversion(typeof(FriendlyDateTime), typeof(DateTime?))]
public class FriendlyDateTimeValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType == typeof(DateTime?))
{
return ((FriendlyDateTime)value).Date;
}
else if (targetType == typeof(FriendlyDateTime))
{
return new FriendlyDateTime(value as DateTime?);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType == typeof(DateTime?))
{
return ((FriendlyDateTime)value).Date;
}
else if (targetType == typeof(FriendlyDateTime))
{
return new FriendlyDateTime(value as DateTime?);
}
return null;
}
}
}
Is there a set of interfaces I could implement that would amke WPF automatically use my converter w/o making the calling class aware.
so going from this
<we:DateTimeRangeElement Date="{Binding Path=Filter.EndTime, Mode=TwoWay, Converter={StaticResource DateTimeConverter}}" />
to this
<we:DateTimeRangeElement Date="{Binding Path=Filter.EndTime, Mode=TwoWay}" />
Upvotes: 3
Views: 85
Reputation: 20850
You can use the TypeConverter attribute on your class, passing in your implementation of IValueConverter as the argument.
For example:
[TypeConverter(typeof(FriendlyDateTimeValueConverter ))]
public class FriendlyDateTime
{
...
}
There is a good explanation at http://blogs.windowsclient.net/rob_relyea/archive/2008/04/10/strings-to-things-or-how-xaml-interprets-attribute-values.aspx.
Upvotes: 2