1
- using System . Windows ;
1
+ using System ;
2
+ using System . Windows ;
2
3
using System . Windows . Interactivity ;
3
4
4
5
namespace RegexDialog . Behaviors
5
6
{
6
7
public class SimplePropertyBindingBehavior : Behavior < DependencyObject >
7
8
{
8
9
private readonly ExpressionEvaluator expressionEvaluator = new ExpressionEvaluator ( ) ;
10
+ private string oldEventName = string . Empty ;
11
+ private EventHandler < EventArgs > eventHandler ;
12
+
13
+ public SimplePropertyBindingBehavior ( )
14
+ {
15
+ eventHandler = new EventHandler < EventArgs > ( OnTriggerEvent ) ;
16
+ }
9
17
10
18
public string PropertyName
11
19
{
@@ -19,13 +27,44 @@ public string PropertyName
19
27
20
28
public object Value
21
29
{
22
- get { return ( object ) GetValue ( ValueProperty ) ; }
30
+ get { return GetValue ( ValueProperty ) ; }
23
31
set { SetValue ( ValueProperty , value ) ; }
24
32
}
25
33
26
34
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
27
35
public static readonly DependencyProperty ValueProperty =
28
- DependencyProperty . Register ( "Value" , typeof ( object ) , typeof ( SimplePropertyBindingBehavior ) , new PropertyMetadata ( null , DependencyPropertyChanged ) ) ;
36
+ DependencyProperty . Register ( "Value" , typeof ( object ) , typeof ( SimplePropertyBindingBehavior ) , new FrameworkPropertyMetadata ( null , FrameworkPropertyMetadataOptions . BindsTwoWayByDefault , DependencyPropertyChanged ) ) ;
37
+
38
+ /// <summary>
39
+ /// Set to false to disable the update of the view from the viewModel
40
+ /// </summary>
41
+ public bool UpdateViewFromViewModel
42
+ {
43
+ get { return ( bool ) GetValue ( UpdateViewFromViewModelProperty ) ; }
44
+ set { SetValue ( UpdateViewFromViewModelProperty , value ) ; }
45
+ }
46
+
47
+ // Using a DependencyProperty as the backing store for UpdateViewFromViewModel. This enables animation, styling, binding, etc...
48
+ public static readonly DependencyProperty UpdateViewFromViewModelProperty =
49
+ DependencyProperty . Register ( "UpdateViewFromViewModel" , typeof ( bool ) , typeof ( SimplePropertyBindingBehavior ) , new PropertyMetadata ( true ) ) ;
50
+
51
+ public string PropertyChangedTriggerEventName
52
+ {
53
+ get { return ( string ) GetValue ( PropertyChangedTriggerEventNameProperty ) ; }
54
+ set { SetValue ( PropertyChangedTriggerEventNameProperty , value ) ; }
55
+ }
56
+
57
+ // Using a DependencyProperty as the backing store for PropertyChangedTriggerEventName. This enables animation, styling, binding, etc...
58
+ public static readonly DependencyProperty PropertyChangedTriggerEventNameProperty =
59
+ DependencyProperty . Register ( "PropertyChangedTriggerEventName" , typeof ( string ) , typeof ( SimplePropertyBindingBehavior ) , new PropertyMetadata ( string . Empty , PropertyChangedTriggerEventNameChanged ) ) ;
60
+
61
+ private static void PropertyChangedTriggerEventNameChanged ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs eventArgs )
62
+ {
63
+ if ( dependencyObject is SimplePropertyBindingBehavior simplePropertyBinding )
64
+ {
65
+ simplePropertyBinding . TriggerEventSubscribe ( ) ;
66
+ }
67
+ }
29
68
30
69
private static void DependencyPropertyChanged ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs eventArgs )
31
70
{
@@ -39,22 +78,83 @@ protected override void OnAttached()
39
78
{
40
79
base . OnAttached ( ) ;
41
80
81
+ TriggerEventSubscribe ( ) ;
42
82
UpdateValue ( ) ;
43
83
}
44
84
45
- private void UpdateValue ( )
85
+ protected override void OnDetaching ( )
86
+ {
87
+ base . OnDetaching ( ) ;
88
+
89
+ TriggerEventUnsubscribe ( ) ;
90
+ }
91
+
92
+ private void TriggerEventSubscribe ( )
93
+ {
94
+ if ( AssociatedObject != null )
95
+ {
96
+ TriggerEventUnsubscribe ( ) ;
97
+ if ( ! PropertyChangedTriggerEventName . Equals ( string . Empty ) )
98
+ {
99
+ oldEventName = PropertyChangedTriggerEventName ;
100
+
101
+ //WeakEventManager<type Final De l'objet, EventArgs>.AddHandler(AssociatedObject, PropertyChangedTriggerEventName, OnTriggerEvent);
102
+ typeof ( WeakEventManager < , > )
103
+ . MakeGenericType ( AssociatedObject . GetType ( ) , typeof ( EventArgs ) )
104
+ . GetMethod ( "AddHandler" )
105
+ . Invoke ( null , new object [ ] { AssociatedObject , PropertyChangedTriggerEventName , eventHandler } ) ;
106
+ }
107
+ }
108
+ }
109
+
110
+ private void TriggerEventUnsubscribe ( )
111
+ {
112
+ if ( ! oldEventName . Equals ( string . Empty ) )
113
+ {
114
+ //WeakEventManager<type Final De l'objet, EventArgs>.RemoveHandler(AssociatedObject, PropertyChangedTriggerEventName, OnTriggerEvent);
115
+ typeof ( WeakEventManager < , > )
116
+ . MakeGenericType ( AssociatedObject . GetType ( ) , typeof ( EventArgs ) )
117
+ . GetMethod ( "RemoveHandler" )
118
+ . Invoke ( null , new object [ ] { AssociatedObject , oldEventName , eventHandler } ) ;
119
+ }
120
+ }
121
+
122
+ private void OnTriggerEvent ( object source , EventArgs args )
46
123
{
47
124
if ( ! PropertyName . Equals ( string . Empty ) )
48
125
{
49
126
try
50
127
{
51
128
expressionEvaluator . Variables [ "obj" ] = AssociatedObject ;
52
- expressionEvaluator . Variables [ "value" ] = Value ; ;
53
129
54
- expressionEvaluator . Evaluate ( $ "obj.{ PropertyName } = value") ;
130
+ object result = expressionEvaluator . Evaluate ( $ "obj.{ PropertyName } ") ;
131
+
132
+ if ( ! result . Equals ( Value ) )
133
+ Value = result ;
55
134
}
56
135
catch { }
57
136
}
58
137
}
138
+
139
+ private void UpdateValue ( )
140
+ {
141
+ if ( UpdateViewFromViewModel && AssociatedObject != null && ! PropertyName . Equals ( string . Empty ) )
142
+ {
143
+ try
144
+ {
145
+ expressionEvaluator . Variables [ "obj" ] = AssociatedObject ;
146
+ object result = expressionEvaluator . Evaluate ( $ "obj.{ PropertyName } ") ;
147
+
148
+ if ( ! result . Equals ( Value ) )
149
+ {
150
+ expressionEvaluator . Variables [ "value" ] = Value ;
151
+
152
+ expressionEvaluator . Evaluate ( $ "obj.{ PropertyName } = value") ;
153
+ }
154
+ }
155
+ catch
156
+ { }
157
+ }
158
+ }
59
159
}
60
160
}
0 commit comments