@HitGirl

WPF как работают свойства зависимостей (DependencyProperty)?

Здравствуйте!
Допустим я реализую свойство зависимостей в классе производном от Button:
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Petzold.SetSpaceProperty
{
    public class SpaceButton: Button
    {
        string txt;

        public string Text
        {
            set
            {
                txt = value;
                Content = SpaceOutText(txt);
            }
            get
            {
                return txt;
            }
        }

        public static readonly DependencyProperty SpaceProperty;

        public int Space
        {
            set
            {
                SetValue(SpaceProperty, value);
            }
            get
            {
                return (int)GetValue(SpaceProperty);
            }
        }

        static SpaceButton()
        {
            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = 1;
            metadata.AffectsMeasure = true;
            metadata.Inherits = true;
            metadata.PropertyChangedCallback += OnSpacePropertyChanged;

            SpaceProperty = DependencyProperty.Register("Space", typeof(int), typeof(SpaceButton), metadata, ValidateSpaceValue);
        }

        private static bool ValidateSpaceValue(object obj)
        {
            int i = (int)obj;
            return i >= 0;
        }

        private static void OnSpacePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            SpaceButton btn = obj as SpaceButton;
            btn.Content = btn.SpaceOutText(btn.Text);
        }

        private object SpaceOutText(string str)
        {
            if (str == null)
                return null;

            StringBuilder build = new StringBuilder();
            foreach (char ch in str)
                build.Append(ch + new string(' ', Space));

            return build.ToString();
        }
    }
}

Потом я добавляю нового владельца в классе производным от Window:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Petzold.SetSpaceProperty
{
    public class SpaceWindow: Window
    {
        public static readonly DependencyProperty SpaceProperty;
        public int Space
        {
            set
            {
                //SetValue(SpaceProperty, value);
                SetValue(SpaceButton.SpaceProperty, value);
            }
            get
            {
                //return (int)GetValue(SpaceProperty);
                return (int)GetValue(SpaceButton.SpaceProperty);
            }
        }

        static SpaceWindow()
        {
            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata() { Inherits = true};

            SpaceProperty = SpaceButton.SpaceProperty.AddOwner(typeof(SpaceWindow));
            SpaceProperty.OverrideMetadata(typeof(SpaceWindow), metadata);       
        }
    }
}

Подскажите, пожалуйста, почему в классе SpaceWindow разрешено использование следующего кода:
SetValue(SpaceButton.SpaceProperty, value);
хотя в данном классе уже переопределено данное свойство (SpaceProperty)?
В чём разница между SetValue(SpaceButton.SpaceProperty, value);и SetValue(SpaceProperty, value);?
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Petzold.SetSpaceProperty
{
    public class SetSpaceProperty : SpaceWindow
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new SetSpaceProperty());
        }
        public SetSpaceProperty()
        {
            Title = "Set space property";
            SizeToContent = SizeToContent.WidthAndHeight;
            ResizeMode = ResizeMode.CanMinimize;
            int[] iSpaces = { 0, 1, 2 };

            Grid grid = new Grid();
            Content = grid;

            for(int i = 0; i < 2; ++i)
            {
                RowDefinition row = new RowDefinition() { Height = GridLength.Auto };
                grid.RowDefinitions.Add(row);
            }
            for(int i = 0; i < iSpaces.Length; ++i)
            {
                ColumnDefinition col = new ColumnDefinition() { Width = GridLength.Auto};
                grid.ColumnDefinitions.Add(col);
            }
            for(int i = 0; i < iSpaces.Length; ++i)
            {
                SpaceButton btn = new SpaceButton() { Text = "Set window Space to "+iSpaces[i], Tag = iSpaces[i], HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center};
                btn.Click += WindowPropertyOnClick;
                grid.Children.Add(btn);
                Grid.SetRow(btn, 0);
                Grid.SetColumn(btn, i);

                btn = new SpaceButton() { Text = "Set button Space to " + iSpaces[i], Tag = iSpaces[i], HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };
                btn.Click += ButtonPropertyOnClick;
                grid.Children.Add(btn);
                Grid.SetRow(btn, 1);
                Grid.SetColumn(btn, i);
            }
        }

        private void ButtonPropertyOnClick(object sender, RoutedEventArgs args)
        {
            SpaceButton btn = args.Source as SpaceButton;
            btn.Space = (int)btn.Tag;
        }

        private void WindowPropertyOnClick(object sender, RoutedEventArgs args)
        {
            SpaceButton btn = args.Source as SpaceButton;
            Space = (int)btn.Tag;
        }
    }
}
  • Вопрос задан
  • 386 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы