#c# #asynchronous #windows-runtime #async-await
#c# #асинхронный #windows-среда выполнения #асинхронный-ожидание
Вопрос:
Я пытаюсь повторно использовать свой пользовательский элемент управления, переопределяя некоторые обработчики событий в производном элементе управления.
Код выглядит следующим образом:
public partial class ControlBase : UserControl {
public ControlBase() {
this.InitializeComponent();
//Buttons
PickFileButton.Click = pickFile;
}
protected virtual async void pickFile(object sender, RoutedEventArgs e) {
var picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
picker.FileTypeFilter.Add(".wmv");
picker.FileTypeFilter.Add(".mp4");
var file = await picker.PickSingleFileAsync();
if (file == null) return;
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
inputFile = file;
InputVideoElement.SetSource(stream, file.ContentType);
}
}
public sealed partial class DerivedControl : ControlBase {
public DerivedControl() {
this.InitializeComponent();
PickFileButton.Click = pickFile;
}
//This handler called twice
protected async override void pickFile(object sender, RoutedEventArgs e) {
base.pickFile(sender, e);
//some other actions
}
Когда я пытаюсь его отладить, я вижу следующее:
Когда я нажимаю кнопку на производном элементе управления, он вызывает override void pickFile()
, который вызывает базовую реализацию. В базовом методе pickFile()
выполнение богато var file = await picker.PickSingleFileAsync();
, а затем производный обработчик pickFile()
вызывается во второй раз, и действия повторяются до var file = await picker.PickSingleFileAsync();
того же момента, после чего я получаю System.UnauthorizedAccessException
.
То же самое действие с базовой кнопкой управления работает нормально. В чем может быть проблема? Заранее спасибо
Ответ №1:
Вы добавляете Click
обработчик событий дважды: один раз в DerivedControl
конструкторе и один раз в ControlBase
конструкторе.
Если вам нужен только один обработчик (как я и ожидал), просто удалите подписку в DerivedControl
конструкторе. Ваш переопределенный метод все равно будет вызван, потому что подписка в ControlBase
конструкторе — это просто делегат, который будет вызывать метод виртуально.
Комментарии:
1. дааа, я только что увидел это, когда просматривал код здесь! Свежий взгляд очень полезен. Спасибо