2013-04-25 2 views
0

Я хотел бы знать, когда на самом деле происходит то, что происходит внутри процесса инициализации элементов управления при запуске приложения WPF?Порядок в хаосе шагов инициализации управления

Когда DP инициализирован? Когда связывание? Когда устанавливается DataContext? Является ли DataContext avaialbe в конструкторе элемента управления? Есть ли какой-то порядок?

Я понял, что я столкнулся с ловушкой, что, как только я установил значение на геттер/сеттер DP внутри конструктора элемента управления, значение DP получает обновление, но сразу же значения возвращаются к значению по умолчанию, которое равно null.

Таким образом, я предполагаю, что конструкторы получают инициализированные сначала, а затем свойства зависимостей.

Может ли кто-нибудь помочь мне с этим?

Редактировать: Только для Рэйчел. Значение dp получает значение 234, а непосредственность возвращается к нулевому значению. Я думаю, что его, потому что конструктор сначала вызван, а затем происходит инициализация dps, которая возвращает dp обратно в null, поскольку значение null является значением по умолчанию. Я думаю об этом неправильно? Каков порядок шагов инициализации объекта управления или зависимости.

class MySuperDuperCoolClass : ContentControl 
{ 
    public MySuperDuperCoolClass() 
    { 
    InitalizeComponents(); 
    this.MySuperDuperProperty = "234"; 
    } 

    public string MySuperDuperProperty 
    { 
    get { return (string)GetValue(MySuperDuperPropertyProperty);} 
    set { SetValue(MySuperDuperPropertyProperty, value);} 
    } 

    public static DependencyProperty MySuperDuperPropertyProperty = 
    DependencyProperty.Register("MySuperDuperProperty", typeof(string), typeof(MySuperDuperCoolClass), 
    new PropertyMetadata(null)); 

} 

ответ

1

Я считаю DispatcherPriority Enum полезно вспомнить точный порядок событий:

  • Отправить
  • Normal - Конструкторы работать здесь
  • DataBind
  • Рендер
  • Loaded
  • фона
  • ContextIdle
  • ApplicationIdle
  • SystemIdle
  • Неактивный
  • Invalid
  • Входной

Как вы можете видеть, Конструкторы задавят фи сначала, а затем привязки данных.

DependencyProperties Инициализируется, когда объект создается, как и любое другое свойство, так что это произойдет до запуска конструктора, чтобы свойство существовало в конструкторе.

Недвижимость DataContext или другое DependencyProperties работает так же, как и любое другое имущество, которое вы устанавливаете. Если вы установите привязку, они будут оцениваться после конструктора. Если вы установите их в XAML, они будут установлены в конструкторе. Если вы установите их в событии Loaded, они будут установлены после того, как все будет построено, привязано и отображено.

Вы также можете найти this SO answer полезно:

Последовательность событий, когда окно создается и показано

В соответствии с просьбой, вот последовательность основных событий в WPF, когда окно создано и показано:

  1. Конструкторы и геттеры/сеттеры называются как объекты, в том числе PropertyChangedCallback, ValidationCallback и т.д. на объектов обновляемых и любых объектах, которые наследуют от них

  2. Поскольку каждый элемент добавляются к визуальному или логическому дереву его Intialized события обжигало, который вызывает стили и триггера быть найдено применяется в дополнении к любому элементу конкретных инициализации вы можно определить [примечание: Initialized события не уволен за листьев в логическом дерева, если нет PresentationSource (например, окно) в корне]

  3. окна и все не -collapsed Visuals на нем измерены, что вызывает ApplyTemplate в каждом элементе управления, что вызывает дополнительные дерево объектов строительство, включая более конструкторы и добытчиков/сеттер

  4. окна и все не разрушились визуалами на нем расположены

  5. окна и его потомки (как логические и визуальные) получают Loaded события

  6. любых привязки данных, которые не удались, когда они были первым набор повторены

  7. окна и его потомки получили возможность оказывать их содержание визуально

Шаги 1-2 выполняются при создании окна, независимо от того, является ли оно показано на рисунке. Другие шаги, как правило, не выполняются до тех пор, пока не будет показано Окна , но они могут произойти раньше, если они запускаются вручную.

Редактировать на основе кода добавляется к вопросу

Ваш метод DependencyProperty.Register выглядит смешно для меня. Подпись метода не соответствует ни одному из overloads для этого метода, и вы используете то, что кажется настраиваемым классом UIProperty, чтобы установить значение по умолчанию вместо обычного PropertyMetadata.

Я могу подтвердить, что если ваш код работает так, как ожидалось, с обычной подписью DependencyProperty.Register, поэтому вероятная причина вашей проблемы будет либо в вашем пользовательском коде, либо в том, как вы используете/устанавливаете свойство.

Код я использовал для быстрой проверки образцов заключается в следующем:

public partial class UserControl1 : ContentControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
     this.TestDependencyProperty = "234"; 
    } 

    public string TestDependencyProperty 
    { 
     get { return (string)GetValue(TestDependencyPropertyProperty); } 
     set { SetValue(TestDependencyPropertyProperty, value); } 
    } 

    public static DependencyProperty TestDependencyPropertyProperty = 
     DependencyProperty.Register("TestDependencyProperty", typeof(string), typeof(UserControl1), 
     new PropertyMetadata(null)); 
} 

и XAML является

<ContentControl x:Class="WpfApplication1.UserControl1" 
       x:Name="TestPanel" ...> 
    <Label Content="{Binding ElementName=TestPanel, Path=TestDependencyProperty}"/> 
</ContentControl> 
+0

Я не уверен, как DispatcherPropery может помочь мне с шагами инициализации элемента управления. Я не вижу связи. –

+0

@snowyguihedgehog Это не то, что вы хотели бы использовать для инициализации элемента управления, однако я считаю, что список приоритетов очень полезен, чтобы помочь запомнить, в какой последовательности выполняются шаги. В частности, у меня 4 выделены жирным шрифтом - Normal (Constructors) DataBinding, рендеринг и загрузка. Если у вас возникла проблема с инициализацией элемента управления, возможно, создайте новый вопрос и включите свой код, чтобы мы могли взглянуть на него :) – Rachel

+0

У меня нет проблем с созданием элемента управления. Я просто хочу знать порядок шагов инициализации. Как насчет того, как вы пытаетесь решить проблему назначения значения в конструкторе в dp. Это не работало для меня хорошо, как я описал в вопросе. –

0

В WPF вы устанавливаете значения по умолчанию для DP с PropertyMetadata не через конструктор.

public partial class UserControl1 : ContentControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    public string TestDependencyProperty 
    { 
     get { return (string)GetValue(TestDependencyPropertyProperty); } 
     set { SetValue(TestDependencyPropertyProperty, value); } 
    } 

    public static DependencyProperty TestDependencyPropertyProperty = 
     DependencyProperty.Register("TestDependencyProperty", typeof(string), typeof(UserControl1), 
     new PropertyMetadata("234")); 
} 
Смежные вопросы