Как получить индекс элемента отправителя из "мультиплексированного" обработчика событий?

62
6

У меня есть один OnDownloadProgress событий OnDownloadProgress для упорядоченного списка элементов BitmapImage, которые я помещаю во FlipView, и мне интересно, как получить индекс отправителя BitmapImage в обработчике событий.

Легко делать такие вещи с объектами, полученными из FrameworkElement, потому что у них есть свойство Tag которое вы можете установить для индекса (или того, что вы хотите). Но событие OnDownloadProgress отправляется не по Image, а по BitmapImage и не имеет Tag.

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

Одним из способов является установка Tag изображения в экземпляр BitmapImage, а затем поиск этого экземпляра в обработчике до тех пор, пока вы не найдете отправителя:

private FlipView PhotosView;

private void AddImages(List<string> photoUrls)
{
PhotosView.Items.Clear();
foreach (var url in photoUrls)
{
var image = new Image();
var source = new BitmapImage(new Uri(url));
source.DownloadProgress += OnDownloadProgress;
image.Source = source;
image.Tag = source;
PhotosView.Items.Add(image);
}
}

private void OnDownloadProgress(object sender, DownloadProgressEventArgs args)
{
int n = 0;
foreach (var item in PhotosView.Items)
{
var image = (Image)item;
if (image.Tag == sender)
{
Debug.WriteLine("image {0} progress={1}%", n, args.Progress);
break;
}
n++;
}
}

Но это кажется неправильным. Лучшим способом было бы поддерживать сопоставление экземпляров BitmapImage с индексом (Dictionary<BitmapImage, int>) и, в то же время, более эффективную с точки зрения скорости, что кажется слишком тяжелым.

Или, наконец, я могу подклассировать BitmapImage и добавить элемент Tag или Index. Ой, подождите... это sealed класс. Поцарапайте это.

Есть ли более простой или более стандартизированный способ делать такие вещи?

спросил(а) 2021-01-19T16:52:51+03:00 2 месяца, 3 недели назад
1
Решение
75

Вы можете сделать это:

private void AddImages(List<string> photoUrls)
{
PhotosView.Items.Clear();
int nextIndex = 0;
foreach (var url in photoUrls)
{
int n = nextIndex++;
var image = new Image();
var source = new BitmapImage(new Uri(url));
source.DownloadProgress += (sender, args) =>
{
Debug.WriteLine("image {0} progress={1}%", n, args.Progress);
};
image.Source = source;
image.Tag = source;
PhotosView.Items.Add(image);
}
}

ответил(а) 2021-01-19T16:52:51+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема