WPF: рдЬрдм рдХреЛрдИ рдкреНрд░реЙрдкрд░реНрдЯреА рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреА рд╣реИ рддреЛ рдХреНрдпрд╛ рдХрд░реЗрдВ

рдкрд░рд┐рдЪрдп


WPF рдПрдХ рдЕрджреНрднреБрдд рддрдХрдиреАрдХ рд╣реИ, рдЬреЛ рдЕрдкрдиреА рд╕рднреА рдХрдорд┐рдпреЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╕рдВрдж рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдкрдХреЛ рдЕрдХреНрд╕рд░ рдорд╛рд░реНрдХрдЕрдк рдирд╣реАрдВ рд▓рд┐рдЦрдирд╛ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдб рдЬреЛ рдкрд╣рд▓реЗ рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдЗрд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВ рдЗрд╕рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдФрд░ рд╢реБрджреНрдз XAML рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ C # рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╡рд┐рднрд┐рдиреНрди рд╣реЗрд▓реНрдкрд░реНрд╕ (рд╣реЗрд▓реНрдкрд░ рдХреНрд▓рд╛рд╕реЗрд╕) рдХреЗ рдмрд┐рдирд╛ рдореЗрд░рд╛ рдПрдХ рднреА рдЖрд╡реЗрджрди рд╕рд░рд▓ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХрдард┐рди рдирд╣реАрдВ рдерд╛ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдРрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдПрдХ рд╕рд╣рд╛рдпрдХ рддреБрд░рдВрдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдиреАрдЪреЗ рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдЧреБрдгреЛрдВ рдореЗрдВ рдмрдВрдзрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдирд┐рд░реНрднрд░рддрд╛ рдЧреБрдг рдирд╣реАрдВ рд╣реИрдВред рдирд┐рдпрдорд┐рдд WPF рдЙрдкрдХрд░рдг рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЗрд╕ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рди рд╕рдХрддреЗ, рд╕рд┐рд╡рд╛рдп рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рд╕рджрд╕реНрдпрддрд╛ рдХреЗ, рдЬреЛ рдПрдорд╡реАрд╡реАрдПрдо рдкреИрдЯрд░реНрди рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреА рдШрдЯрдирд╛рдПрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рд╕рдмрд╕реЗ рдЖрдо рдЙрджрд╛рд╣рд░рдг рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдФрд░ рдЗрд╕рдХреА рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдкрддреНрддрд┐ рд╣реИред рддреЛ рд╣рдо рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ:

<PasswordBox Password={Binding OtherProperty} /> 

рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗ рдХрд┐ рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдмрд╛рдВрдзрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдХреНрдпреЛрдВ рдирд╣реАрдВ рджреАред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рджреЗрдВред

рдпрджрд┐ рдЖрдк рдореЗрд░реЗ рддрд░реНрдХ рдХреЛ рдирд╣реАрдВ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдЕрдВрддрд┐рдо рдХреЛрдб рдФрд░ рдЬреАрдердм рдХрд╛ рд▓рд┐рдВрдХ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ


рдФрд░ рдЗрд╕рд▓рд┐рдП! рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдВрдзрди рдХреА рддрд░рд╣ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рдеред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рджреЛ рддрд░рд╣ рд╕реЗ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реИред рдЙрдкрд░реЛрдХреНрдд рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рд╣рд╛рдпрдХ рдХреЛ рддреАрди рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
  1. рджреГрд╢реНрдп рддрддреНрд╡ рд╕рдВрдкрддреНрддрд┐
  2. рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдШрдЯрдирд╛ рдмрджрд▓реЗрдВ
  3. рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдбреЗрдЯрд╛ рд╕реЛрд░реНрд╕

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреНрд░рдорд╢рдГ рд╣реЛрдЧрд╛: рдкрд╛рд╕рд╡рд░реНрдб рд╕рдВрдкрддреНрддрд┐, рдкрд╛рд╕рд╡рд░реНрдбрдЪреЗрдирдб рдЗрд╡реЗрдВрдЯ рдФрд░ рдЕрдиреНрдпрдкреНрд░реЛрдкрд░реЗрдЯреА рдХрд╛ рд╕реНрд░реЛрддред

рдЖрдк рдЬреЛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЗ рд╣реИрдВред рдЖрдЗрдП рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рддрдВрддреНрд░ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ - рд╡реНрдпрд╡рд╣рд╛рд░ред

рд╡реНрдпрд╡рд╣рд╛рд░ рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рдПрдХ рджреГрд╢реНрдп рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ: рд╡реНрдпрд╡рд╣рд╛рд░ рдФрд░ рд╡реНрдпрд╡рд╣рд╛рд░ <рдЯреА> рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ред рдЙрдирдХреЗ рдорддрднреЗрджреЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИред рдорд╣рд╛рди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВрдиреЗ рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛ред

рдПрдХ рдХреЛрдб рд▓рд┐рдЦрдирд╛


System.Windows.Interactivity.dll рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝реЗрдВред рдпрд╣ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдмреНрд▓реЗрдВрдб рдПрд╕рдбреАрдХреЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдФрд░ рд╡рд┐рдЬреБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ рдЕрд╕реЗрдВрдмрд▓реА рд╕рд┐рд▓реЗрдХреНрд╢рди рд╡рд┐рдВрдбреЛ рдХреЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рдиреНрд╕ рд╕реЗрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред

рд╡реНрдпрд╡рд╣рд╛рд░ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ <T> :

 public class DependecyPropertyBehavior : Behavior<DependencyObject> { } 

рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ DependencyObjec t рдХреЛ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рд╣рдо рдХрд┐рд╕реА рднреА рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╡рд░реНрдЧ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓ рдкрд╛рд╕рд╡рд░реНрдбрдмреЙрдХреНрд╕ рдирд╣реАрдВред

рдСрдкрд░реЗрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реЛрдЧрд╛ред рдПрдХ рд╕рдВрдкрддреНрддрд┐ рд╕реЗ рдПрдХ рд╕реНрд░реЛрдд рд╕реЗ рдмрд╛рдВрдзрдиреЗ рдХреЗ рд▓рд┐рдП:
  1. рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдШрдЯрдирд╛ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддреЗ рд╣реИрдВред
  2. рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рд╣рдо рд╕реНрд░реЛрдд рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдореВрд▓реНрдп рд▓рд┐рдЦрддреЗ рд╣реИрдВред

рд╡рд╛рдкрд╕ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХреЗ рд▓рд┐рдП:
  1. рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╣рдо рдЙрд╕ рдХреНрд╖рдг рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рд╕реЗ рд╕реНрд░реЛрдд рдорд╛рди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИред
  2. рд╣рдо рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдореВрд▓реНрдп рд▓рд┐рдЦрддреЗ рд╣реИрдВред

рдЙрдкрд░реЛрдХреНрдд рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП, рддреАрди рдЧреБрдг рдмрдирд╛рдПрдВ:

 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); } } 


рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЧреБрдг рдФрд░ рдЕрджреНрдпрддрди рдЧреБрдг рд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВ, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдмрдВрдзрди рд╕рдВрдкрддреНрддрд┐, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рд╕рдВрдкрддреНрддрд┐ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред

рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рднреА рдЗрдирдкреБрдЯ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд OnAttached () рд╡рд┐рдзрд┐ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред рджреГрд╢реНрдп рддрддреНрд╡ рдореЗрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕рдВрд▓рдЧреНрди рдХрд░рддреЗ рд╕рдордп рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдмрд╛рдж рдХреЛ рдПрд╕реЛрд╕рд┐рдПрдЯреЗрдбрдУрдмрдЬреЗрдХреНрдЯ рдХреНрд▓рд╛рд╕ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рд╣реЛрдиреЗ рдкрд░ OnDetaching () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╣рдореЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреГрд╢реНрдп рддрддреНрд╡ рдФрд░ рдШрдЯрдирд╛ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╕реНрддреБрдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреГрд╢реНрдп рддрддреНрд╡ рдХреА рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕реВрдЪрдирд╛ рджреЗрдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдЙрдирдХреА рдкреНрд░рд╛рдкреНрддрд┐ рдФрд░ рд╕рджрд╕реНрдпрддрд╛ рджрд┐рдЦрд╛рддрд╛ рд╣реИред

рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдореИрдВрдиреЗ рд╡рд┐рднрд┐рдиреНрди рдЕрд╢рдХреНрдд рдЬрд╛рдВрдЪреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рддрд╛рдХрд┐ рдореЗрд░рд╛ рдзреНрдпрд╛рди рди рднрдЯрдХреЗред рдХрдХреНрд╖рд╛ рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╡реЗ рдореМрдЬреВрдж рд╣реИрдВред

 private Delegate _handler; private EventInfo _eventInfo; private PropertyInfo _propertyInfo; 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); } 

рдКрдкрд░ рдХреЗ рдХреЛрдб рдореЗрдВ рдПрдХ 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(); // Getting property. if (Property == null) { PresentationTraceSources.DependencyPropertySource.TraceData( TraceEventType.Error, 1, "Target property not defined." ); return; } _propertyInfo = elementType.GetProperty(Property, BindingFlags.Instance | BindingFlags.Public); if (_propertyInfo == null) { PresentationTraceSources.DependencyPropertySource.TraceData( TraceEventType.Error, 2, string.Format("Property \"{0}\" not found.", Property) ); return; } // Getting event. if (UpdateEvent == null) return; _eventInfo = elementType.GetEvent(UpdateEvent); if (_eventInfo == null) { PresentationTraceSources.MarkupSource.TraceData( TraceEventType.Error, 3, string.Format("Event \"{0}\" not found.", UpdateEvent) ); return; } _handler = CreateDelegateForEvent(_eventInfo, EventFired); _eventInfo.AddEventHandler(AssociatedObject, _handler); } protected override void OnDetaching() { if (_eventInfo == null) return; if (_handler == null) return; _eventInfo.RemoveEventHandler(AssociatedObject, _handler); } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (e.Property.Name != "Binding") return; if (AssociatedObject == null) return; if (_propertyInfo == null) 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() { if (AssociatedObject == null) return; if (_propertyInfo == null) return; Binding = _propertyInfo.GetValue(AssociatedObject, null); } } } 


Github

Source: https://habr.com/ru/post/In215249/


All Articles