1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Windows;

namespace GSdk.Shared.Windows.Properties
{
    public struct Property<T>
    {
        Property(DependencyProperty prop)
        {
            m_DependencyProperty = prop;
        }

        readonly DependencyProperty m_DependencyProperty;

        public static implicit operator Property<T>(PropertyBase prop)
        {
            return new Property<T>(prop.DependencyProperty);
        }

        public static implicit operator DependencyProperty(Property<T> prop)
        {
            return prop.m_DependencyProperty;
        }

        public T this[DependencyObject obj]
        {
            get { return (T)obj.GetValue(m_DependencyProperty); }
            set { obj.SetValue(m_DependencyProperty, value); }
        }
    }

    public abstract class PropertyBase
    {
        public readonly DependencyProperty DependencyProperty;

        protected PropertyBase(DependencyProperty prop)
        {
            DependencyProperty = prop;
        }
    }

    public sealed class Property<TContainer, TValue> : PropertyBase
    {
        public Property(Expression<Func<TContainer, TValue>> accessor)
            : base(DependencyProperty.Register(accessor.MemberToString(), typeof(TValue), typeof(TContainer)))
        {
        }
        public Property(Expression<Func<TContainer, TValue>> accessor, PropertyMetadata metadata)
            : base(DependencyProperty.Register(accessor.MemberToString(), typeof(TValue), typeof(TContainer), metadata))
        {
        }
        public Property(Expression<Func<TContainer, TValue>> accessor, PropertyMetadata metadata, ValidateValueCallback callback)
            : base(DependencyProperty.Register(accessor.MemberToString(), typeof(TValue), typeof(TContainer), metadata, callback))
        {
        }
    }

    public sealed class AttachedProperty<TContainer, TValue> : PropertyBase
    {
        public AttachedProperty(Expression<Func<Property<TValue>>> accessor)
            : base(DependencyProperty.RegisterAttached(accessor.MemberToString().Substring(0,accessor.MemberToString().Length - "Property".Length), typeof(TValue), typeof(TContainer)))
        {
        }
        public AttachedProperty(Expression<Func<Property<TValue>>> accessor, PropertyMetadata metadata)
            : base(DependencyProperty.RegisterAttached(accessor.MemberToString().Substring(0, accessor.MemberToString().Length - "Property".Length), typeof(TValue), typeof(TContainer), metadata))
        {
        }
        public AttachedProperty(Expression<Func<Property<TValue>>> accessor, PropertyMetadata metadata, ValidateValueCallback callback)
            : base(DependencyProperty.RegisterAttached(accessor.MemberToString().Substring(0, accessor.MemberToString().Length - "Property".Length), typeof(TValue), typeof(TContainer), metadata, callback))
        {
        }
    }
}