#c_sharp #wpf #многопоточность #timer
Не знаю как можно реализовать следующие: Когда мышь входит в область label(MouseEnter), если мышь остается в области label 3 секунды, то создается новый контрол. При этом надо сделать так чтобы главный поток не останавливался, а если таймер делать в другом потоке, то надо чтобы этот поток имел возможность создавать элементы на форме(в главном потоке). Если мышь выходит за пределы label и 3 секунды не прошло то ничего не создается соответственно.
Ответы
Ответ 1
Всё просто. При заходе мыши в лейбл, делаем 2 задачи: первая закончится через 3 секунды, вторая закончится когда мышь покинет лейбл. Ждем конца любой из задач. После этого проверяем - если закончилась первая, то добавляем элемент, если вторая - то ничего не делаем. Все это запускается асинхронно, никаких таймеров не надо. Пример кода: class Wnd : Window { public Wnd() { var lbl = new Label() { Content = "I AM LABEL" }; var sp = new StackPanel() {Orientation = Orientation.Vertical}; sp.Children.Add(lbl); lbl.MouseEnter += async (sender, args) => { var tcs = new TaskCompletionSource(); MouseEventHandler leave = null; leave = (sender2, args2) => { lbl.MouseLeave-=leave; tcs.SetResult(0); }; lbl.MouseLeave+=leave; var delayTask = Task.Delay(3000); await Task.WhenAny(tcs.Task, delayTask); if (delayTask.IsCompleted) sp.Children.Add(new Label() {Content="3 sec passed!"}); }; this.Content = sp; } } В действии: Ответ 2
public partial class MainWindow { private CancellationTokenSource _cts = new CancellationTokenSource(); public MainWindow() { InitializeComponent(); lbl.MouseLeave += (s, arg) => { _cts?.Cancel(); }; lbl.MouseEnter += async (s, arg) => { _cts = new CancellationTokenSource(); try { await Task.Delay(TimeSpan.FromSeconds(3), _cts.Token); //Your action here Trace.WriteLine("3 secs passed"); } catch (TaskCanceledException) { //Ignore: leave before 3 sec } }; } }
Комментариев нет:
Отправить комментарий