Pull to refresh

Comments 48

особой разницы в производительности не заметил даже на моём стареньком Omnia 7
UFO just landed and posted this here
вертикальный скроллбар перевёрнут как и listbox, но находится как и прежде справа, горизонтальный — теперь будет находится сверху :)
UFO just landed and posted this here
Может я покажусь Вам странным, но обычную сортировку данных по дате нельзя сделать?..
можно, но тогда надо будет скроллить список вниз к первому (после сортировки к последнему) элементу, а с этим возникали некоторые проблемы
А можно подробнее, какие проблемы?
Наверное имело в виду добавление элементов.
верно, а также фича/бага при включённой виртуализации, когда список не скроллился до конца, и часть последнего сообщения была видна на половину
Аааа, ладно, не буду я углубляться, просто это настолько непривычно — париться из-за такой вещи, что мне даже сказать нечего…
Мда, я думал что будет что то более полезное.
Хотя бы про то, как сделать цвета в соответствии темы. Имеется в виду красный/темно-красный (как на картинке), синий/темно-синий.

Для вас, самое простое и правильное решение, это при стыковать контейнер элементов вниз. И проблема сразу исчезает.
что то типо этого:
<ListBox x:Name="Messages" ItemTemplate="{StaticResource ChatMessage}"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel VerticalAlignment="Bottom" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>
А что, с цветами есть какая-то проблема?
А вы знаете какие они должны быть точно? Я вот например не нашел не где. Пытался подобрать и как то рассчитать, не получилось.
Вы пытались подобрать пару каждому цвету? Тут просто надо сверху на акцентный цвет полупрозрачный слой накладывать и все.
Совпадает на всех темах?
даже если нет, так ли это важно?
с цветами я поступил следующим образом:

Добавил конвертер
public class RelativeColorConverter : IValueConverter
{
	#region IValueConverter

	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		var color = (Color)value;
		var delta = System.Convert.ToInt32(parameter) / 100D;

		return Color.FromArgb(color.A, (byte)(color.R * delta), (byte)(color.G * delta), (byte)(color.B * delta));
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		var color = (Color)value;
		var delta = 100D / System.Convert.ToInt32(parameter);

		return Color.FromArgb(color.A, (byte)(color.R * delta), (byte)(color.G * delta), (byte)(color.B * delta));
	}

	#endregion
}

и определил кисть в ресурсах, как
<Converters:RelativeColorConverter x:Key="RelativeColorConverter" />
<SolidColorBrush x:Key="PhoneDarkAccentBrush"
				 Color="{Binding Source={StaticResource PhoneAccentColor}, Converter={StaticResource RelativeColorConverter}, ConverterParameter=60}" />


Т.е. затемнённый акцентный цвет — это 60% от акцентного света

Плохой вариант. Надо от каждого цвета отнимать константу, а не уменьшать на заданный процент.
какова в таком случае должна быть константа?
У нас используется «50». Надо отсортировать значения RGB по возрастанию и отнимать эту константу. Если значения цвета меньше константы — остаток дополнительно отнять от следующего цвета.
тогда уж лучше через преобразование в HSB или YUV это сделать. У последнего даже преобразование простое ru.wikipedia.org/wiki/YUV
Действительно лучше, спасибо.
Я делал преобразование в HSV и уменьшал яркость (Value) на 30%.
первоначальное решение была как раз таким, но когда начинаешь подгружать историю, то список начинает прыгать как ненормальный
Это уже проблема подгрузки, но не как не лист бокса) Извращать так лист бокс, из за того что лень сделать нормально загрузку данных, не есть good!
Костыль ориентированное программирование. Разве так трудно сделать сортировку по датам и вставку элемента в нужное место?
абсолютно не трудно, но при добавлении элементов в начало, список начинает «прыгать» вниз
Пересчитать индекс текущего элемента нельзя что ли?
можно, но сообщения могут быть разной высоты, и при добавлении элемента с «нестандартной высотой» список будет смещаться на разницу в высоте
поверьте, я вырвал не один волос на голове, когда пытался просчитать положение видимой части, дабы элементы оставались на своих прежних местах, в итоге всё делалось для удобства пользователя
На StackOverflow попадались вопросы других участников конкурса (вы ведь для VK делали?) с аналогичными проблемами.
угу, и в группе отвечал, правда уже когда сам дошёл до этого
Ха! У нас на проекте точно такой же костыль используется :-) Но скроллинг после этого стал какой-то не такой. Как минимум — нельзя остановить анимацию скроллинга тапом (в обычном листе можно). Лучше всё же сделать по нормальному.
Да, вы правы. При таком решении возникают проблемы со скроллингом. Копать дальше уже не стал ибо и так уже костыль хитрый.
Это очень неграмотный подход. Вы про сортировку списков слышали? Про интерфейс ICollectionView, класс CollectionViewSource?

1. Создайте ObservableCollection с объектами сообщений.
2. Оберните его в ICollectionView
var collectionViewSource = new CollectionViewSource { Source = this.messages }; this.view = collectionViewSource.View; // далее буду называть его view
3. Настройте сортировку view (ICollectionView.SortDescriptions)
4. Привяжите контрол к view (любой наследник ItemsControl умеет работать с ICollectionView)
5. Используйте все плюшки ICollectionView в MVVM-стиле
6. PROFIT
И как это связано со скроллингом?
У ICollectionView есть методы для управления текущим элементом в списке, а текущий элемент всегда должен находиться в области видимости.
Вы пробовали? Проблема в том, что при виртуализированном листбоксе да ещё не дай бог с элементами разной высоты ScrollIntoView работает некорректно хоть ты тресни.
Ну я эту проблему решал по-другому. Использовал ScrollView и ItemsControl. К данным написал конвертер, который сортирует список в нужном порядке и добавил attached dp DockScrollToBottom, при установлении которого я вешался на изменение прокрутки у ScrollView и прокручивал на разницу добавленного элемента. В данном случае ScrollView будет работать c физическим скроллингом, в отличие от логического в ListBox, тогда у вас пропадёт баг прокрутки на неполноценный элемент, а также никаких косяков не будет с горизонтальной прогруткой.

Но вот меня интересует вопрос, решали ли вы проблемы со смайлами ;-), я говорю не про текстовые смайлы из unicode, а полноценные графические?
Пардон, в ScrollViewer вешался на изменения в ViewportHeight, а не на изменение прокрутки.
если я не ошибаюсь, такой вариант не использует виртуализацию?
Подход довольно таки интересный (спасибо, возьму на заметку), но не решает проблему потребления памяти. Если элементов очень много, и каждый содержит сложное отображение, то приложение начинает жутко тормозить, и если не предпринять соответствующих мер, может вообще вылететь со StackOwerflowException. VirtualizingStackPanel как раз решает эту проблему.
Ну вроде как это должно исправить ситуацию, просто мне было не нужно:
<ItemsControl
VirtualizingStackPanel.IsVirtualizing=«True»
ScrollViewer.CanContentScroll=«True»>
<ItemsControl.ItemsPanel>
<VirtualizingStackPanel />
</ItemsControl.ItemsPanel>
</ItemsControl>
Sign up to leave a comment.

Articles