Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
.NET 4.x

Кроп элементов ListBox'a при изменении размера контейнера с включенной виртуализацией

17.02.2013, 16:01. Показов 2967. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Уважаемые форумчане, помогите пожалуйста тупому школьнику новичку в WPF.

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

Имеется листбокс, заполненный элементами, состоящими преимущественно из текста (в примере ниже - гуйди):
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<Window x:Class="CroppedElements.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">
    <ListBox Padding="2" 
             HorizontalContentAlignment="Stretch" 
             ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
             ItemsSource="{Binding GuidCollection}" 
             VirtualizingStackPanel.IsVirtualizing="True">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border HorizontalAlignment="Stretch" 
                        BorderThickness="1" 
                        BorderBrush="#FF2CBBF0" 
                        CornerRadius="3" 
                        Background="Beige" 
                        Padding="5" 
                        SnapsToDevicePixels="True" 
                        Margin="2">
                    <TextBlock FontSize="13" 
                               Foreground="Black" 
                               TextWrapping="Wrap" 
                               VerticalAlignment="Center" 
                               Text="{Binding}"/>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>
C#
1
2
GuidCollection = new ObservableCollection<Guid>(Enumerable.Range(0, 3000).Select(i => Guid.NewGuid()));
DataContext = this;


Шаблон элементов сделан таким образом, чтобы занимать все доступное место по горизонтали.
При изменении размера окна не влезающий текст переносится на новую строчку и рамка подстраивается под ширину окна и высоту текста:



Однако, если продолжать уменьшать окно, в какой-то момент рамка перестает уменьшаться по горизонтали и обрезается с правого края:



Поведение это наблюдается только при включенной виртуализации и установке свойства TextWrapping на что угодно, кроме NoWrap.
Ни виртуализацию, ни враппинг отключить нет возможности в связи с требованиями к интерфейсу, а такое поведение жутким образом бесит - нужно, чтобы правый край рамки было всегда видно.
Включение горизонтальной прокрутки - не вариант, к сожалению.

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

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



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

Если кто-то хочеть поиграться - пример во вложении (VS 2010).

Предложившему самый элегантный вариант с удовольствием подарю очень толстый плюс.
Вложения
Тип файла: zip CroppedElements.zip (14.8 Кб, 18 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.02.2013, 16:01
Ответы с готовыми решениями:

Как при изменении размера содержимого не менять размер контейнера
Есть меню, при выделении тега а, делаю подчеркивание и увеличиваю шрифт, соответственно увеличивается ширина li, хотел узнать как избежать...

Прокрутка Treeview с включенной виртуализацией
Имеется длинющий TreeМiew, заполненный циклично. У TreeView включен режим VirtualizingPanel.IsVirtualizing=&quot;True&quot; ...

Запрет изменения размера формы и элементов при изменении шрифта и его размера
Здравствуйте. К слову вопрос название темы. А именно как запретить изменять размер формы и элементов при изменении шрифта Изменить...

10
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
20.02.2013, 23:42
kolorotur, все что нашел - вы уже применили. Пишут - не задокументированный баг.
Частично решается использованием wrapPanel,но он не предназначен для Item'ов из-за этого в некоторых случаях жутко виснет.

Не по теме:

поищу потом еще,уже сил нету по буржуйских форумах лазить)

1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
21.02.2013, 14:37  [ТС]
Цитата Сообщение от Noob.net Посмотреть сообщение
Пишут - не задокументированный баг.
Это прискорбно
Из-за такой ерунды приложение выглядит как голимая дешевка.

Цитата Сообщение от Noob.net Посмотреть сообщение
Частично решается использованием wrapPanel,но он не предназначен для Item'ов из-за этого в некоторых случаях жутко виснет.
Да, WrapPanel в данном случае не катит из-за расположения в нем элементов и отсутствия виртуализации.

Цитата Сообщение от Noob.net Посмотреть сообщение
поищу потом еще,уже сил нету по буржуйских форумах лазить
Мне вот тоже надоело лазить, потому запостил здесь

Спасибо за помощь!

P.S. Предложение с толстым плюсом остается в силе
0
79 / 79 / 12
Регистрация: 07.01.2012
Сообщений: 167
22.02.2013, 16:40
Наковырял решение только для VirtualizingStackPanel.VirtualizationMod e="Recycling" но очень похоже на упомянутое:
Цитата Сообщение от kolorotur Посмотреть сообщение
просчитыванию максимальной ширины видимых элементов в виртуальной панели
как говорится в правильном вопросе уже половина ответа
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<ListBox Name="listBox" 
             Padding="2" 
             HorizontalContentAlignment="Stretch"
             ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
             ItemsSource="{Binding GuidCollection}"             
             VirtualizingStackPanel.IsVirtualizing="True"
             VirtualizingStackPanel.VirtualizationMode="Recycling">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel 
                    MaxWidth="{Binding ActualWidth, ElementName=listBox}"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border Name="border" 
                        BorderThickness="1" 
                        BorderBrush="#FF2CBBF0" 
                        CornerRadius="3" 
                        Background="Beige" 
                        Padding="5"
                        Margin="2">                        
                        <TextBlock 
                               TextWrapping="Wrap" 
                               Text="{Binding}" >
                        </TextBlock>                  
                </Border>                   
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.02.2013, 22:14
kolorotur, в крайнем случае: напишите на microsoft, я им написал, они в 4.5 фреймворке поправили
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
23.02.2013, 14:34  [ТС]
Цитата Сообщение от Talent Посмотреть сообщение
только для VirtualizingStackPanel.VirtualizationMod e="Recycling"
Спасибо! Хоть граница и обрезается, но хотя бы уже не так сильно.
С использованием Recycling, правда, у меня возникает другая проблема: во время прокрутки может внезапно вылететь ArgumentNullException со стек трейсом, ведущим куда-то в дебри фреймворка (в реальном проекте к одному списку биндится список, содержащий элементы разных классов, имеющие разные свойства. Конкретный дизайн выбирается через DataTemplate - похоже, проблема где-то здесь).

Цитата Сообщение от Psilon Посмотреть сообщение
в крайнем случае: напишите на microsoft, я им написал, они в 4.5 фреймворке поправили
Что ж мне, пятого фреймворка ждать?
Мы тут еще на 4.5 даже не перешли
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 14:36
kolorotur, ну все же для будущих поколений избавление от костылей - тоже неплохо. Вы же не эгост. Да и сами 5 фреймворк переживете, надеюсь Так что самому еще пользоваться
0
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
23.02.2013, 18:17
Psilon, об этом им уже писали - не поправили. Видел на форумах ребят,которые жаловались на это целыми командами,а мелкие ничего не сделали.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
23.02.2013, 19:01
Noob.net, Стал опен-сорсом. Исходники ASP.NET MVC были открыты с самого начала, но сейчас вообще весь стек ASP.NET стал опен-сорсным и принимает исправления извне. WPF — нет, и, откровенно говоря, вы бы и не захотели смотреть на код WPF: он ужасен (прим. перев.: можно оценить VirtualizingStackPanel).

.NET sources: VirtualizingStackPanel
Сижу ковыряю сорцы VirtualizingStackPanel в надежде получить требуемое мне поведение (адекватный пиксельный скроллинг при элементах разного размера). Ковыряю в рефлекторе, потому что мелкомягкие в очередной раз не удосужились выложить последнюю версию сорцов.

Весь код класса в подобных методах:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private void MeasureChild (
  ref IItemContainerGenerator generator,
  ref IContainItemStorage itemStorageProvider,
  ref object parentItem,
  ref bool hasUniformOrAverageContainerSizeBeenSet,
  ref double computedUniformOrAverageContainerSize,
  ref bool computedAreContainersUniformlySized,
  ref IList items,
  ref object item,
  ref IList children,
  ref int childIndex,
  ref bool visualOrderChanged,
  ref bool isHorizontal,
  ref Size childConstraint,
  ref Rect viewport,
  ref VirtualizationCacheLength cacheSize,
  ref VirtualizationCacheLengthUnit cacheUnit,
  ref bool foundFirstItemInViewport,
  ref double firstItemInViewportOffset,
  ref Size stackPixelSize,
  ref Size stackPixelSizeInViewport,
  ref Size stackPixelSizeInCacheBeforeViewport,
  ref Size stackPixelSizeInCacheAfterViewport,
  ref Size stackLogicalSize,
  ref Size stackLogicalSizeInViewport,
  ref Size stackLogicalSizeInCacheBeforeViewport,
  ref Size stackLogicalSizeInCacheAfterViewport,
  ref bool mustDisableVirtualization,
  bool isBeforeFirstItem,
  bool isAfterFirstItem,
  bool isAfterLastItem,
  bool skipActualMeasure,
  bool skipGeneration,
  ref bool hasBringIntoViewContainerBeenMeasured,
  ref bool hasVirtualizingChildren)
0
 Аватар для Konctantin
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
23.02.2013, 20:04
походу MS полностью переключили свое внимание на HTML5+JS, а на WPF забили (а технология очень даже хороша, если бы довели ее до ума)
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
07.02.2014, 14:24  [ТС]
Оставлю тут на случай, если кто-то натолкнется на данную проблему.

По контракту поддержки написали в МС багрепорт от имени компании, отвер пришел довольно быстро и был весьма однозначным: да, проблему воспроизвести удалось. Да, это баг в алгоритмах просчета ширины элементов виртуальной панели. Однако, цитирую: "в ближайшем будущем планов по его устранению нет".
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.02.2014, 14:24
Помогаю со студенческими работами здесь

Растягивание элементов управления при изменении размера формы
Имеется игра пятнашки, клетки заданы как двумерный массив кнопок, стоит задача увеличивать все это в размере, если ставить anchor на...

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

Смещение объектов в окне при изменении размера элементов системы
Здравствуйте! Суть проблемы: Купил новый бук с большим разрешением. Стандартные размеры элементов системы стоят на 125% (100%-считается...

Изменение размера UserControl при изменении размера элемента на нем
Здравствуйте. У меня на UserControl находится TextBox. Выполняю построение. В конструкторе переношу мой UserControl на форму. Меняю в...

Qml изменение размера Canvas при изменении размера окна
Может есть какой нибудь способ, чтобы при изменении размера окна (в моем случае window) изменялся размер рисунка Canvas (увеличивался или...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru