Разрабатывается чат вконтакте, который поддерживает медиавложения. Был написан обращённый список ListView
, поддерживающий виртуализацию данных и использующий интерфейс ISupportIncrementalLoading
. Получение сообщений происходит по сети от апи вконтакте. Шаблон сообщения содержит контрол, который занимается созданием медиавложений (документы, фото, виде, товары и т.д.).
Проблема заключается в следующем: При первом появлении сообщения вложения, если они есть, отображаются хорошо. Однако, если скролить дальше или зайти в беседу с другим человеком, то могут появится эти самые вложения в сообщениях, в которых их быть не должно. Из-за чего такое может происходить? Я грешу на эту самую виртуализацию. Если использовать виртуализацию данных прямого доступа, то проблема исчезнет? Такая же самая ошибка встречается и при построении записей на стене. Т.е. в новых элементах появляются куски ранее просмотренных записей.
Код
<DataTemplate x:DataType="models:Message"
x:Key="InPrivateMessageTemplate">
<attachments:MessagesAttachmentsController Attachments="{x:Bind Attach}" />
</DataTemplate>
// то, что создаёт вложения.
public class MessagesAttachmentsController : Control
{
private StackPanel _layouRoot;
private MediaItemPresenter _mediaItemPresenter;
public MessagesAttachmentsController()
{
DefaultStyleKey = typeof(MessagesAttachmentsController);
}
public MediaItemPresenter MediaItemPresenter =>
_mediaItemPresenter ?? (_mediaItemPresenter = new MediaItemPresenter());
public List<IAttachment> Attachments
{
get => (List<IAttachment>)GetValue(AttachmentsProperty);
set => SetValue(AttachmentsProperty, value);
}
public static readonly DependencyProperty AttachmentsProperty =
DependencyProperty.Register(nameof(Attachments), typeof(List<IAttachment>), typeof(MessagesAttachmentsController), new PropertyMetadata(null, (s, e) =>
{
if (Equals(e.NewValue, e.OldValue) || e.NewValue == null)
{
return;
}
(s as MessagesAttachmentsController)?.ReBuild();
}));
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_layouRoot = GetTemplateChild("LayoutRoot") as StackPanel;
ReBuild();
}
private void ReBuild()
{
if (_layouRoot == null || Attachments == null)
{
return;
}
_layouRoot.Children.Clear();
foreach (var item in Attachments)
{
switch (item)
{
case Core.Entity.Attachments.Sticker sticker:
{
CreateStiсker(sticker);
return;
}
case Core.Entity.Attachments.Link link:
{
CreateLink(link);
return;
}
case IAttachmentPreview ap:
{
MediaItemPresenter.Attachments.Add(ap);
break;
}
default:
break;
}
}
if (_mediaItemPresenter != null)
{
_layouRoot.Children.Add(_mediaItemPresenter);
}
}
private void CreateStiсker(Core.Entity.Attachments.Sticker sticker)
{
var s = new Sticker
{
PhotoUrl = sticker.Photo128,
Size = 128
};
_layouRoot.Children.Add(s);
}
private void CreateLink(Core.Entity.Attachments.Link link)
{
var l = new Link
{
PhotoUrl = link.Photo?.Photo604,
Title = link.Title,
Description = link.Description,
Url = link.Url
};
_layouRoot.Children.Add(l);
}
}
При проверке данных в
public static readonly DependencyProperty AttachmentsProperty =
DependencyProperty.Register(nameof(Attachments),
typeof(List<IAttachment>), typeof(MessagesAttachmentsController),
new PropertyMetadata(null, (s, e) =>
{
if (Equals(e.NewValue, e.OldValue) || e.NewValue == null) // Всегда будет равен false
{
return;
}
(s as MessagesAttachmentsController)?.ReBuild(); // Вот тут все и дублируется
}));
Удалите проверку и все будет работать корректно.
Либо попробуйте не вызывать ReBuild()
в OnApplyTemplate()
Как я уже писал, всё дело в виртуализации. Наилучшее решение, которое нашёл на данный момент - принудительная очистка панели темплейта, содержащая все вложения. Делается посредством вызова Children.Clear(), после чего панель заполняется новыми элементами. Ну и да, всё это необходимо делать асинхронно через
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, handler),
иначе происходят сильные тормоза
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Мне нужно, чтобы переходя на любой роут моего приложения koa всегда передавал файл indexhtml, т
имеется ту ду лист, создается заметка, которая в формате li#draggable > p добавляется в ul в колонку PENDINGхочу реализовать drag&drop, чтобы заметки из колонки...
Ребят всем добрый вечер! Помогите сделать чтобы прелоадер работал во время загрузки страницы а по середине в процентах показывало процент...