Как получить индекс элемента отправителя из "мультиплексированного" обработчика событий?
У меня есть один 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
класс. Поцарапайте это.
Есть ли более простой или более стандартизированный способ делать такие вещи?
Вы можете сделать это:
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);
}
}