Как сделать недействительным макет списка из пользовательских дочерних элементов - PullRequest
0 голосов
/ 22 марта 2010

У меня есть пользовательская панель для списка

<ItemsPanelTemplate x:Key="FloatPanelTemplate">
    <Controls:FloatPanel x:Name="CardPanel" />
</ItemsPanelTemplate>

Панель размещает свои дочерние элементы, используя свойства зависимостей X и Y. Это все работает хорошо, когда FloatPanel используется сам по себе - я использую FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure для свойств зависимостей дочерних элементов, чтобы сообщить FloatPanel перерисовать его макет.

Когда я использую его в Listbox (код выше), он в первый раз хорошо рисует, но когда я перетаскиваю дочерние элементы (которые изменяют X и Y элемента), он не уведомляет Listbox, что ему нужно перерисовать панель FloatPanel. дети. Я думаю, что проблема связана с тем фактом, что каждый элемент в связанной коллекции обернут с ListBoxItem.

Надеюсь, я описал то, что я делаю достаточно хорошо, чтобы кто-то мог сказать мне, как заставить панель (или ее дочерние элементы) сказать, что она должна снова выполнить процедуры Layout. Как я уже сказал, это работает один раз (первоначальное рисование), но затем перетаскивание элементов не работает (Listbox не знает, что его дочерние элементы изменились и его необходимо ретранслировать.) Если я перетаскиваю элемент, а затем изменяю размер окна, список выводит макет и предметы нарисованы в их новых местах.

Как мне уведомить ListBox (или, что более важно, FloatPanel в ItemsPanelTemplate), что он должен сделать проход Layout?

Ответы [ 2 ]

1 голос
/ 22 марта 2010

Вместо этого попробуйте FrameworkPropertyMetadataOptions.AffectsParentMeasure и FrameworkPropertyMetadataOptions.AffectsParentArrange.

Эти имена ... Слава Богу за разум, да?

Как вы заметили, поскольку ListBoxItem является непосредственным родителем макета вашего элемента, изменения свойств зависимостей, которые влияют на макет родителя, не будут "видны" панелью, которая находится дальше по визуальному дереву.

Так что вместо этого вам, к сожалению, нужно будет пройти по визуальному дереву, пока не найдете элемент, производный от Panel, и не вызовите его метод InvalidateArrange.

DependencyObject obj=this;
while ( (obj=VisualTreeHelper.GetParent(obj)) != null) {
    Panel p = obj as Panel;
    if (p != null) {
        p.InvalidateArrange();
        break;
    }
}

Это ужасно, но, возможно, у гуру WPF будет лучшее предложение.

0 голосов
/ 13 мая 2015

Вы уверены, что ваша панель ListBox или ListView не имеет неправильного размера, потому что имеет ...

ScrollViewer.CanContentScroll="True"

... какое значение по умолчанию?

Когда элемент управления списком находится в этом режиме и когда он прокручивается вниз, в нижней части внизу его панели могут быть дополнительные пробелы, чтобы убедиться, что встроенный элемент выстроен в top его внутреннего ScrollViewer, и это может показаться, что ScrollViewer - и, следовательно, элемент управления списком - не изменяет свой размер.

Чтобы избежать пробелов в нижней части панели, необходимо включить прокрутку по пикселям для элемента управления ListBox или ListView:

ScrollViewer.CanContentScroll="False"

или в коде:

ScrollViewer.SetCanContentScroll(list_ctrl, false);

См. Также: WPF ListView без встроенной прокрутки

...