Есть ли метод, аналогичный RegisterClassHandler, для значений DependencyProperty? - PullRequest
0 голосов
/ 02 июня 2018

Я знаю, что вы можете использовать класс EventManager для регистрации обработчика класса в перенаправленном событии, чтобы все экземпляры класса отвечали, когда это событие вызывается для этого объекта класса:

EventManager.RegisterClassHandler( typeof( TextBox ), Control.MouseDoubleClickEvent,
    new RoutedEventHandler( ( S, E ) => ( E.OriginalSource as TextBox )?.SelectAll( ) ) );

То, что я ищу, это способ сделать что-то похожее с прикрепленным DependencyProperty, чтобы обеспечить DataBinding для всех экземпляров типа элемента управления, которые используют это конкретное свойство.

В соответствии с Минимальный, полный и проверяемый пример требования ...

App.xaml.cs:

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace MCVE {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : INotifyPropertyChanged {
        public static readonly DependencyProperty FooProperty;

        public event PropertyChangedEventHandler PropertyChanged;

        static App( ) {
            EventManager.RegisterClassHandler(
                typeof( TextBox ), Control.MouseDoubleClickEvent,
                new RoutedEventHandler(
                    ( S, E ) => ( E.OriginalSource as TextBox )?.SelectAll( ) ) );
            FooProperty = DependencyProperty.RegisterAttached(
                    "Foo", typeof( string ), typeof( App) );
            //Is it possible to bind the FooProperty of all Window objects to
            //the FooSource property defined below in similar fashion 
            //to how one can call RegisterClassHandler above?
        }

        [STAThread]
        public static int Main( ) {
            App program = new App( );
            program.InitializeComponent( );
            return program.Run( );
        }

        protected override void OnStartup( StartupEventArgs e ) {
            this.FooSource = "Baz";
            base.OnStartup( e );
        }

        public static string GetFoo( Window w ) =>
            w.GetValue( FooProperty ).ToString( );
        public static void SetFoo( Window w, string value ) =>
            w.SetValue( FooProperty, value );

        private string _fooSource = "Bar";
        public string FooSource {
            get => this._fooSource;
            set {
                this._fooSource = value;
                this.PropertyChanged?.Invoke(
                    this, new PropertyChangedEventArgs( "FooSource" ) );
            }
        }
    }
}

Таким образом, желаемое поведение будет таким, что после запуска программы любое окносозданный впоследствии имел бы значение FooProperty, установленное на "Baz" через некоторое поведение привязки данных (так что если свойство FooSource изменилось, то также изменилось бы каждое свойство windows FooProperty).

Этовозможно?

1 Ответ

0 голосов
/ 19 июня 2018

Вам нужно только добавить еще один обработчик событий для события Window.Loaded в конструкторе App.

private App()
{
    EventManager.ResisterClassHandler(typeof(Window), Window.LoadedEvent,
        (RoutedEventHandler)((s, e) =>
            ((Windows)s).SetBinding(FooProperty, new Binding("FooSource")
            {
                Source = this,
            }
        ));
}

И я считаю, что это просто неосторожный промах, тип владельца FooProperty должно быть typeof(App), но не typeof(Window).

...