рдкрд░рд┐рдЪрдп
WPF рдПрдХ рдЕрджреНрднреБрдд рддрдХрдиреАрдХ рд╣реИ, рдЬреЛ рдЕрдкрдиреА рд╕рднреА рдХрдорд┐рдпреЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╕рдВрдж рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдкрдХреЛ рдЕрдХреНрд╕рд░ рдорд╛рд░реНрдХрдЕрдк рдирд╣реАрдВ рд▓рд┐рдЦрдирд╛ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдб рдЬреЛ рдкрд╣рд▓реЗ рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВ рдЗрд╕рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдФрд░ рд╢реБрджреНрдз XAML рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ C # рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╡рд┐рднрд┐рдиреНрди рд╣реЗрд▓реНрдкрд░реНрд╕ (рд╣реЗрд▓реНрдкрд░ рдХреНрд▓рд╛рд╕реЗрд╕) рдХреЗ рдмрд┐рдирд╛ рдореЗрд░рд╛ рдПрдХ рднреА рдЖрд╡реЗрджрди рд╕рд░рд▓ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХрдард┐рди рдирд╣реАрдВ рдерд╛ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдРрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдПрдХ рд╕рд╣рд╛рдпрдХ рддреБрд░рдВрдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдиреАрдЪреЗ рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдЧреБрдгреЛрдВ рдореЗрдВ рдмрдВрдзрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдирд┐рд░реНрднрд░рддрд╛ рдЧреБрдг рдирд╣реАрдВ рд╣реИрдВред рдирд┐рдпрдорд┐рдд WPF рдЙрдкрдХрд░рдг рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЗрд╕ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рди рд╕рдХрддреЗ, рд╕рд┐рд╡рд╛рдп рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рд╕рджрд╕реНрдпрддрд╛ рдХреЗ, рдЬреЛ
рдПрдорд╡реАрд╡реАрдПрдо рдкреИрдЯрд░реНрди рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреА рдШрдЯрдирд╛рдПрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рд╕рдмрд╕реЗ рдЖрдо рдЙрджрд╛рд╣рд░рдг
рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдФрд░ рдЗрд╕рдХреА
рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдкрддреНрддрд┐ рд╣реИред рддреЛ рд╣рдо рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ:
<PasswordBox Password={Binding OtherProperty} />
рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗ рдХрд┐ рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдмрд╛рдВрдзрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдХреНрдпреЛрдВ рдирд╣реАрдВ рджреАред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рджреЗрдВред
рдпрджрд┐ рдЖрдк рдореЗрд░реЗ рддрд░реНрдХ рдХреЛ рдирд╣реАрдВ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдЕрдВрддрд┐рдо рдХреЛрдб рдФрд░ рдЬреАрдердм рдХрд╛ рд▓рд┐рдВрдХ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ
рдФрд░ рдЗрд╕рд▓рд┐рдП! рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдВрдзрди рдХреА рддрд░рд╣ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рдеред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рджреЛ рддрд░рд╣ рд╕реЗ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реИред рдЙрдкрд░реЛрдХреНрдд рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рд╣рд╛рдпрдХ рдХреЛ рддреАрди рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
- рджреГрд╢реНрдп рддрддреНрд╡ рд╕рдВрдкрддреНрддрд┐
- рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдШрдЯрдирд╛ рдмрджрд▓реЗрдВ
- рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдбреЗрдЯрд╛ рд╕реЛрд░реНрд╕
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреНрд░рдорд╢рдГ рд╣реЛрдЧрд╛:
рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдкрддреНрддрд┐,
рдкрд╛рд╕рд╡рд░реНрдбрдЪреЗрдирдб рдЗрд╡реЗрдВрдЯ рдФрд░
рдЕрдиреНрдпрдкреНрд░реЛрдкрд░реЗрдЯреА рдХрд╛ рд╕реНрд░реЛрддред
рдЖрдк рдЬреЛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЗ рд╣реИрдВред рдЖрдЗрдП рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рддрдВрддреНрд░ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ - рд╡реНрдпрд╡рд╣рд╛рд░ред
рд╡реНрдпрд╡рд╣рд╛рд░ рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рдПрдХ рджреГрд╢реНрдп рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ: рд╡реНрдпрд╡рд╣рд╛рд░ рдФрд░
рд╡реНрдпрд╡рд╣рд╛рд░ <рдЯреА> рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ред рдЙрдирдХреЗ рдорддрднреЗрджреЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИред рдорд╣рд╛рди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВрдиреЗ рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛ред
рдПрдХ рдХреЛрдб рд▓рд┐рдЦрдирд╛
System.Windows.Interactivity.dll рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝реЗрдВред рдпрд╣ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдмреНрд▓реЗрдВрдб рдПрд╕рдбреАрдХреЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдФрд░ рд╡рд┐рдЬреБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ рдЕрд╕реЗрдВрдмрд▓реА рд╕рд┐рд▓реЗрдХреНрд╢рди рд╡рд┐рдВрдбреЛ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рдиреНрд╕ рд╕реЗрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред
рд╡реНрдпрд╡рд╣рд╛рд░ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ
<T> :
public class DependecyPropertyBehavior : Behavior<DependencyObject> { }
рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░
DependencyObjec t рдХреЛ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рд╣рдо рдХрд┐рд╕реА рднреА рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╡рд░реНрдЧ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓
рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдирд╣реАрдВред
рдСрдкрд░реЗрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реЛрдЧрд╛ред рдПрдХ рд╕рдВрдкрддреНрддрд┐ рд╕реЗ рдПрдХ рд╕реНрд░реЛрдд рд╕реЗ рдмрд╛рдВрдзрдиреЗ рдХреЗ рд▓рд┐рдП:
- рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдШрдЯрдирд╛ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддреЗ рд╣реИрдВред
- рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рд╣рдо рд╕реНрд░реЛрдд рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдореВрд▓реНрдп рд▓рд┐рдЦрддреЗ рд╣реИрдВред
рд╡рд╛рдкрд╕ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХреЗ рд▓рд┐рдП:
- рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╣рдо рдЙрд╕ рдХреНрд╖рдг рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рд╕реЗ рд╕реНрд░реЛрдд рдорд╛рди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИред
- рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдореВрд▓реНрдп рд▓рд┐рдЦрддреЗ рд╣реИрдВред
рдЙрдкрд░реЛрдХреНрдд рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП, рддреАрди рдЧреБрдг рдмрдирд╛рдПрдВ:
public string Property { get; set; } public string UpdateEvent { get; set; } public static readonly DependencyProperty BindingProperty = DependencyProperty.RegisterAttached( "Binding", typeof(object), typeof(DependecyPropertyBehavior), new FrameworkPropertyMetadata { BindsTwoWayByDefault = true } ); public object Binding { get { return GetValue(BindingProperty); } set { SetValue(BindingProperty, value); } }
- рд╕рдВрдкрддреНрддрд┐ - рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдирд╛рдо рдЬреЛ рдмрдВрдзрди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ;
- UpdateEvent - рдЙрд╕ рдШрдЯрдирд╛ рдХрд╛ рдирд╛рдо рдЬреЛ рд╣рдорд╛рд░реА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдореВрд▓реНрдп рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреА рд╕реВрдЪрдирд╛ рджреЗрддрд╛ рд╣реИ;
- рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХрд┐рд╕реА рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рд╕реЗ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрднрд░рддрд╛ рдЧреБрдг рд╣реИред рдЖрдк рдкрд░рд┐рдЪрд┐рдд рд╕реНрдиреИрдк рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ,
рдЧреБрдг рдФрд░
рдЕрджреНрдпрддрди рдЧреБрдг рд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВ, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред
рдмрдВрдзрди рд╕рдВрдкрддреНрддрд┐, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рд╕рдВрдкрддреНрддрд┐ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред
рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рднреА рдЗрдирдкреБрдЯ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд
OnAttached () рд╡рд┐рдзрд┐ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред рджреГрд╢реНрдп рддрддреНрд╡ рдореЗрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕рдВрд▓рдЧреНрди рдХрд░рддреЗ рд╕рдордп рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдмрд╛рдж рдХреЛ
рдПрд╕реЛрд╕рд┐рдПрдЯреЗрдбрдУрдмрдЬреЗрдХреНрдЯ рдХреНрд▓рд╛рд╕ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рд╣реЛрдиреЗ рдкрд░
OnDetaching () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╣рдореЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреГрд╢реНрдп рддрддреНрд╡ рдФрд░ рдШрдЯрдирд╛ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╕реНрддреБрдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕реВрдЪрдирд╛ рджреЗрдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдЙрдирдХреА рдкреНрд░рд╛рдкреНрддрд┐ рдФрд░ рд╕рджрд╕реНрдпрддрд╛ рджрд┐рдЦрд╛рддрд╛ рд╣реИред
рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдореИрдВрдиреЗ рд╡рд┐рднрд┐рдиреНрди
рдЕрд╢рдХреНрдд рдЬрд╛рдВрдЪреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рддрд╛рдХрд┐ рдореЗрд░рд╛ рдзреНрдпрд╛рди рди рднрдЯрдХреЗред рдХрдХреНрд╖рд╛ рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡реЗ рдореМрдЬреВрдж рд╣реИрдВред
private Delegate _handler; private EventInfo _eventInfo; private PropertyInfo _propertyInfo; protected override void OnAttached() { Type elementType = AssociatedObject.GetType();
рдКрдкрд░ рдХреЗ рдХреЛрдб рдореЗрдВ рдПрдХ
CreateDelegateForEvent () рд╡рд┐рдзрд┐ рд╣реИ ред рдпрд╣ рд░рди рдЯрд╛рдЗрдо рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдИрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╕рдм рдХреЗ рдмрд╛рдж, рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рд╣рдо рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВред рд╕рдВрдХрд▓рди рдХрд░рддреЗ рд╕рдордп, рдкреНрд░рддрд┐рдирд┐рдзрд┐
рдПрдХреНрд╢рди рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд░рддрд╛
рд╣реИ , рдЬреЛ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ
EventFired () рд╣реИ ред рдЗрд╕рдореЗрдВ, рд╣рдо рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХреЗ рдореВрд▓реНрдп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░реЗрдВрдЧреЗред
private static Delegate CreateDelegateForEvent(EventInfo eventInfo, Action action) { ParameterExpression[] parameters = eventInfo .EventHandlerType .GetMethod("Invoke") .GetParameters() .Select(parameter => Expression.Parameter(parameter.ParameterType)) .ToArray(); return Expression.Lambda( eventInfo.EventHandlerType, Expression.Call(Expression.Constant(action), "Invoke", Type.EmptyTypes), parameters ) .Compile(); }
рдпрд╣ рдСрдкрд░реЗрд╢рди рдХрд╛рдлреА рд╕рдВрд╕рд╛рдзрди рдЧрд╣рди рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм рд╡реНрдпрд╡рд╣рд╛рд░ рдЬреБрдбрд╝рд╛ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдорд╛рдирдХрд░ рд▓рдЪреАрд▓реЗрдкрди рдХрд╛ рддреНрдпрд╛рдЧ рдХрд░рдХреЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдХреЗрд╡рд▓
рдирд┐рдпрдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдлрд┐рд░, рдорд╣рдВрдЧрд╛ рд╕рдВрдХрд▓рди рдХреЗ рдмрдЬрд╛рдп,
рд░реВрдЯрдбреЗрдирд╡реЗрдВрдЯрд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рдж,
EventFired () рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВред рд╕рдордпрдкреВрд░реНрд╡ рдЕрдиреБрдХреВрд▓рди рдмреБрд░рд╛рдИ рд╣реИред
EventFired () рд╡рд┐рдзрд┐ рдЕрддреНрдпрдВрдд рд╕рд░рд▓ рд╣реИ, рдпрд╣ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдорд╛рди рд▓рд┐рдЦрддрд╛ рд╣реИ:
private void EventFired() { Binding = _propertyInfo.GetValue(AssociatedObject, null); }
рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдмрджрд▓рдиреЗ рдкрд░ рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдЫреЛрдЯреА рдЪреАрдЬ рдмрдЪреА рд╣реИред
рдУрд╡рд░рд░рд╛рдЗрдбреЗрдмрд▓ рдСрдирдкреНрд░реЛрдкрд░реНрдЯреАрдЪреЗрдВрдЬ () рдкрджреНрдзрддрд┐, рдЬреЛ рд╡рд░реНрдЧ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдЧреБрдгреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддреА рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИред рдЪреВрдВрдХрд┐ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдиреЗ рдкрд░
рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдкреНрд░реЙрдкрд░реНрдЯреА рднреА рдмрджрд▓ рдЬрд╛рддреА рд╣реИ, рд╣рдореЗрдВ рдмрд╕ рдЗрд╕рдХреЗ рдирдП рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (e.Property.Name != "Binding") return; if (_propertyInfo.CanWrite) _propertyInfo.SetValue(AssociatedObject, e.NewValue, null); base.OnPropertyChanged(e); }
рд╕рдм рдареАрдХ рд▓рдЧрдиреЗ рд▓рдЧрд╛ рд╣реИред рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ ... рдПрдХ
StackOverflowException рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдШрдЯрдирд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рдореЗрдВ рд╕рджрд╕реНрдпрддрд╛ рджреА рдЬрд╛рддреА рд╣реИред рдИрд╡реЗрдВрдЯ рдореЗрдВ рд╕реНрд░реЛрдд рдорд╛рди рдмрджрд▓рддрд╛ рд╣реИ, рдФрд░ рдЬрдм рд╕реНрд░реЛрдд рдмрджрд▓рддрд╛ рд╣реИ, рддреЛ
рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдкреНрд░реЙрдкрд░реНрдЯреА рдмрджрд▓ рдЬрд╛рддреА рд╣реИ, рдЬреЛ рд╣рдореЗрдВ
рдСрдирдкреНрд░реЛрдкрд░реНрдЯреАрдЪреЗрдВрдЬреНрдб () рд╡рд┐рдзрд┐ рдкрд░ рд╡рд╛рдкрд╕ рд▓рд╛рддреА рд╣реИред рдкреНрд░рддреНрдпрд╛рд╡рд░реНрддрдиред
рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╕рдорд╛рдзрд╛рди рдкреБрд░рд╛рдиреЗ рдФрд░ рдирдП рд╕рдВрдкрддреНрддрд┐ рдореВрд▓реНрдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдЬреЛрдбрд╝рдирд╛ рд╣реИ:
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (e.Property.Name != "Binding") return; object oldValue = _propertyInfo.GetValue(AssociatedObject, null); if (oldValue.Equals(e.NewValue)) return; if (_propertyInfo.CanWrite) _propertyInfo.SetValue(AssociatedObject, e.NewValue, null); base.OnPropertyChanged(e); }
рдпрд╣рд╛рдВ рд╣рдо рдпрд╣ рдзрд╛рд░рдгрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ
рдмрд░рд╛рдмрд░ () рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╣рдореЗрд╢рд╛
рдЧрд▓рдд рдирд╣реАрдВ рд▓реМрдЯрдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╣рдорд╛рд░рд╛ рд╕рд╣рд╛рдпрдХ рддреИрдпрд╛рд░ рд╣реИ!
рдкрд░рд┐рдгрд╛рдо
рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:
<StackPanel xmlns:local="clr-namespace:DependecyPropertyBehaviorNamesapce" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" > <PasswordBox> <i:Interaction.Behaviors> <local:DependecyPropertyBehavior UpdateEvent="PasswordChanged" Property="Password" Binding="{Binding Text, ElementName=TestTextBox}" /> </i:Interaction.Behaviors> </PasswordBox> <TextBox x:Name="TestTextBox" /> </StackPanel>
рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ,
TextBox рдФрд░
PasswordBox рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд┐рдП рдЧрдП рдорд╛рдиреЛрдВ рдХреЛ рдмрджрд▓ рджреЗрдЧрд╛ред

рдирд┐рд╖реНрдХрд░реНрд╖
рд╣рдордиреЗ рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХрд╛рд░реНрдп рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рд╣реИ, рдЬрд┐рд╕рдиреЗ рд╢реБрд░реВ рдореЗрдВ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛ред рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рджреЛрдиреЛрдВ рддрд░реАрдХреЛрдВ рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рдФрд░ рдЖрдк рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдФрд░ рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рдЕрдВрддрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд┐рд╕реА рднреА рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╡рд╣рд╛рд░ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдореИрдВ рдЕрдкрдиреЗ рдкрд╣рд▓реЗ рд▓реЗрдЦ, рдкрд╛рда рдореЗрдВ рдЕрд╢реБрджреНрдзрд┐ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рдорд╛рдлреА рдорд╛рдБрдЧрддрд╛ рд╣реВрдБред
рдЬреИрд╕рд╛ рдХрд┐ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЕрдВрддрд┐рдо рдХреЛрдб:
рддреНрд╡рд░рд┐рдд рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╢реВрдиреНрдп рдЬрд╛рдБрдЪ рдирд╣реАрдВ using System; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Windows; using System.Windows.Interactivity; using Expression = System.Linq.Expressions.Expression; namespace DependecyPropertyBehaviorNamesapce { public class DependecyPropertyBehavior : Behavior<DependencyObject> { private Delegate _handler; private EventInfo _eventInfo; private PropertyInfo _propertyInfo; public static readonly DependencyProperty BindingProperty = DependencyProperty.RegisterAttached( "Binding", typeof(object), typeof(DependecyPropertyBehavior), new FrameworkPropertyMetadata { BindsTwoWayByDefault = true } ); public object Binding { get { return GetValue(BindingProperty); } set { SetValue(BindingProperty, value); } } public string Property { get; set; } public string UpdateEvent { get; set; } protected override void OnAttached() { Type elementType = AssociatedObject.GetType(); _propertyInfo = elementType.GetProperty(Property, BindingFlags.Instance | BindingFlags.Public); _eventInfo = elementType.GetEvent(UpdateEvent); _handler = CreateDelegateForEvent(_eventInfo, EventFired); _eventInfo.AddEventHandler(AssociatedObject, _handler); } protected override void OnDetaching() { _eventInfo.RemoveEventHandler(AssociatedObject, _handler); } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (e.Property.Name != "Binding") return; object oldValue = _propertyInfo.GetValue(AssociatedObject, null); if (oldValue.Equals(e.NewValue)) return; if (_propertyInfo.CanWrite) _propertyInfo.SetValue(AssociatedObject, e.NewValue, null); base.OnPropertyChanged(e); } private static Delegate CreateDelegateForEvent(EventInfo eventInfo, Action action) { ParameterExpression[] parameters = eventInfo .EventHandlerType .GetMethod("Invoke") .GetParameters() .Select(parameter => Expression.Parameter(parameter.ParameterType)) .ToArray(); return Expression.Lambda( eventInfo.EventHandlerType, Expression.Call(Expression.Constant(action), "Invoke", Type.EmptyTypes), parameters ) .Compile(); } private void EventFired() { Binding = _propertyInfo.GetValue(AssociatedObject, null); } } }
рд╕рднреА рдЬрд╛рдБрдЪреЛрдВ рдХреЗ рд╕рд╛рде рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг using System; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Windows; using System.Windows.Interactivity; using Expression = System.Linq.Expressions.Expression; namespace DependecyPropertyBehaviorNamesapce { public class DependecyPropertyBehavior : Behavior<DependencyObject> { private Delegate _handler; private EventInfo _eventInfo; private PropertyInfo _propertyInfo; public static readonly DependencyProperty BindingProperty = DependencyProperty.RegisterAttached( "Binding", typeof(object), typeof(DependecyPropertyBehavior), new FrameworkPropertyMetadata { BindsTwoWayByDefault = true } ); public object Binding { get { return GetValue(BindingProperty); } set { SetValue(BindingProperty, value); } } public string Property { get; set; } public string UpdateEvent { get; set; } protected override void OnAttached() { Type elementType = AssociatedObject.GetType();
Github