Bas Hamer
Bas Hamer

Reputation: 324

is there a set of interfaces you can implement to avoid having a Converter in WPF binding

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

Answers (1)

Greg Sansom
Greg Sansom

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

Related Questions