Как в Xamarin изменить цвет фона кнопки всего на 1 секунду и вернуть ей исходный цвет? - PullRequest
3 голосов
/ 20 июня 2020

Я разрабатываю небольшое приложение в Xamarin и хочу изменить цвет фона кнопки всего на 1 секунду , когда пользователь нажимает ее. Я пытаюсь использовать следующий код:

var auxColor = btnCancel.BackgroundColor;    // saving the original color (btnCancel is the button name)
btnCancel.BackgroundColor = Color.Red;       // changing the color to red
Task.Delay(1000).Wait();                     // waiting 1 second            
btnCancel.BackgroundColor = auxColor;        // restoring the original color

Но я получаю следующую последовательность:

1- Сохранение исходного цвета 2- ОЖИДАНИЕ 1 СЕКУНДУ 3 Изменение цвета на красный 4 Сразу восстановление цвета

Кто-нибудь знает как решить эту проблему?

Ответы [ 2 ]

3 голосов
/ 20 июня 2020

Вы можете использовать Device.StartTimer следующим образом.

В событии нажатия кнопки:

private void OnButtonClicked(object sender, EventArgs e)
{                    
    var auxColor = btnCancel.BackgroundColor;    // saving the original color 
    btnCancel.BackgroundColor = Color.Red; 

    Device.StartTimer(TimeSpan.FromSeconds(1), () =>
    {
        btnCancel.BackgroundColor = auxColor;             
        return false;
    });
}

Для взаимодействия с элементами пользовательского интерфейса вы можете использовать BeginInvokeOnMainThread например:

Device.StartTimer (new TimeSpan (0, 0, 1), () =>
{
    // do something every 1 second
    Device.BeginInvokeOnMainThread (() => 
    {
      // interact with UI elements
    });
    return true; // runs again, or false to stop
});

См. Device.StartTimer docs.

2 голосов
/ 20 июня 2020

Похоже, вы вызываете steatements в методе, выполняемом основным потоком, который также отвечает за рендеринг. Это означает, что ваш оператор

Task.Delay(1000).Wait();                     // waiting 1 second   

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

Существуют разные возможные подходы к решению вашей проблемы, самый простой подход - использовать asyn c , чтобы позволить потоку пользовательского интерфейса продолжить работу в фоновом режиме:

private async void blink()
{
    var auxColor = btnCancel.BackgroundColor;    // saving the original color (btnCancel is the button name)
    btnCancel.BackgroundColor = Color.Red;       // changing the color to red
    await Task.Delay(1000)                       // waiting 1 second            
    btnCancel.BackgroundColor = auxColor;        // restoring the original color
}

Другим возможным решением может быть установка исходного цвета после завершения задержки с использованием исходного контекста потока (UI) снова:

var auxColor = btnCancel.BackgroundColor;        // saving the original color (btnCancel is the button name)
btnCancel.BackgroundColor = Color.Red;           // changing the color to red
Task.Delay(1000).ContinueWith((T) =>             // waiting 1 second  
    {
        btnCancel.BackgroundColor = auxColor;    // restoring the original color
    }, TaskScheduler.FromCurrentSynchronizationContext());
...