2013-07-11 11 views
2

Итак, если у меня есть привязка, помещенная на ширину дочернего объекта, который связывает ее с ее родительским ActualWidth, что произойдет?WPF Что происходит, когда ширина ребенка привязана к фактической ширине родителя

Я предполагаю, что родительский размер измеряет ширину, которую хочет ребенок, а потом ребенок указывает ширину родительского 0, тогда родитель получает фактическое пространство во время аранжировки и пытается дать ребенку нуль, так как ребенок не сделал хочу любой. Тогда фактическая ширина пространства, заданного родительскому, должна заставить привязку изменить ширину дочернего элемента. На этом этапе я предполагаю, что макет выполняется снова.

Однако это предполагает, что привязка не распространяется так быстро. Я все еще туман, когда связанное значение распространяется на цель. Все зависит от того, изменяется ли фактическое значение родительской способности. Это происходит после завершения компоновки? а затем обновление связанных частей? Все ли привязки прерывают текущий исполняемый код, чтобы обновить целевое значение? если нет, то не будет ли вызвать проблемы, если один связывание распространяется изменение, которое требует перерисовки, то другой связывание распространяется другое изменение, которое вызывает перерисовки и т.д.

Некоторые люди спрашивали, что моя фактическая проблема была:

Поэтому изначально я хотел иметь контрольный стрейч, чтобы заполнить доступное пространство. Достаточно просто, но я хотел, чтобы это было в scrollviewer. Scrollviewer дает бесконечное пространство своим детям во время измерения. Поэтому вместо этого вы можете привязать ширину и высоту дочернего элемента управления к фактической ширине и фактической высоте родителя; макет делает второй проход, и все кажется набуханием.

Однако позже у меня возникли проблемы подобного рода, растягивающие элемент управления в контрольной таблице, но затем выяснилось, что я могу установить minwidth и alignment = stretch, чтобы растянуть его.

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

Итак, теперь я использую привязку для одного и метод minwidth plus alignment для другого. В любом случае это интересовало только это, чтобы убедиться, что способ, которым я занимаюсь, не создает странных ошибок позже.

Я надеюсь, что макет не запускается сразу, когда ширина или высота изменяется, но вместо того, чтобы система перепроверяет для изменения размера периодически

+0

Просто не беспокойтесь. Вероятно, у вас есть элемент управления, у которого есть предыдущий размер родителя. Просто отбросьте элемент управления на Stackpanel и не делайте _not_, установите его ширину. Он будет иметь Stacpanel.ActualWidth. –

+1

Там могут быть проблемы с «рекурсивными» связями, такими как это приводит к проблемам с обновлением. Например, попробуйте вложенные сетки внутри каждого другого с общими ссылками на общий размер области. Вы можете попасть в некоторые штаты, где сетки сражаются за свои измерения, и вы заканчиваете с мерцанием между разными размерами, постоянно обновляя макеты. Лучше избегать создания этих типов условий. –

+1

Я пробовал это очень широко. Проблема в том, что я не могу разместить точку останова внутри мерной коррекции сетки, поэтому я не могу видеть каждый шаг и быть уверенным, что все происходит так, как я думаю. Я продолжаю думать, что на этом сайте нужен раздел для общего обсуждения того, как все работает вместо конкретных вопросов. Есть ли место, куда я могу пойти, и просто открыть диалог чата с группой людей, которые знают wpf? –

ответ

3

В соответствии с DispatherPriority enum, DataBinding происходит до Rendering.

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

Таким образом, связывание будет пытаться оценить, прежде чем вынести происходит.

Однако рендеринг может привести к обновлению вашей привязки, поэтому, если процесс рендеринга родительской панели увеличит ширину панели (например, родительская панель, размещенная внутри другой панели, которая автоматически растягивает свои дочерние элементы до 100 % пространства, например, Grid или последний элемент в DockPanel), то он инициирует обновление привязки и увеличивает ширину дочернего элемента во время цикла рендеринга.

Вторая часть this SO answer также может помочь вам разобраться. Обратите внимание на # 6 тоже.

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

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

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

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

  3. окно и все не-разрушился Видеоряд на ней Измеряется, что вызывает ApplyTemplate на каждый контроле, что приводит к дополнительному Строительство объектов, включая больше конструкторов и геттеры/сеттеры

  4. окна и все не-разрушился Видеоряд на нем расположены

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

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

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

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