Изменить цвет кнопки формы Xamarin

2

Я новичок в xamarin, я хочу изменить цвет кнопки на клике после того, как он вернется к цвету по умолчанию, как только процесс будет завершен. См. Код ниже. Как можно повторно отобразить кнопку во время выполнения. Команда выполняла первый поэтому я обработал его в click.This функция должна работать для android и iOS.

public class RippleButton : Button
{
    private readonly Color _defaultBackgroundColor = Color.FromRgb(255, 87, 34);
    private readonly Color _clickedBackgroundColor = Color.FromRgb(76, 175, 80);

    public ICommand ClickCommand
    {
        get { return (ICommand)GetValue(ClickCommandProperty); }
        set
        {
            SetValue(ClickCommandProperty, value);
        }
    }


    public static readonly BindableProperty ClickCommandProperty = BindableProperty.Create(
                                                   propertyName: nameof(ClickCommand),
                                                   returnType: typeof(ICommand),
                                                   declaringType: typeof(RippleButton),
                                                   defaultValue: null,
                                                   defaultBindingMode: BindingMode.TwoWay,
                                                   propertyChanged: OnClickCommandChanged);

    private static void OnClickCommandChanged(BindableObject bindable, object oldvalue, object newvalue)
    {
    }

    public RippleButton()
    {
        const int animationTime = 10;


        TextColor = Color.FromRgb(255, 255, 255);
        BackgroundColor = _defaultBackgroundColor;

        Clicked += async (sender, e) =>
        {
            var btn = (RippleButton)sender;

            BackgroundColor = Color.FromRgb(76, 175, 80);

            ClickCommand?.Execute(btn.CommandParameter);

            await btn.ScaleTo(1.2, animationTime);
            await btn.ScaleTo(1, animationTime);

            BackgroundColor = _defaultBackgroundColor;
        };
    }

    private void ChangeColorOfButton()
    {
        BackgroundColor = _clickedBackgroundColor;
        Device.StartTimer(TimeSpan.FromSeconds(0.25), () =>
        {
            BackgroundColor = _defaultBackgroundColor;
            return false;
        });
    }
}
  • 0
    Вы хотите изменить цвет кнопки во время нажатия кнопки и вернуть ее обратно, когда отпустите?
  • 0
    Да. После завершения процесса он должен вернуться к цвету по умолчанию.
Теги:
xamarin
xamarin.forms
mvvm

1 ответ

6
Лучший ответ

Для ожидания выполнения команды - одним из способов было бы определить асинхронную команду. Стивен Клири поделился некоторыми удивительными шаблонами о том, как реализовать асинхронные команды.

Вы можете определить команду async как:

public interface IAsyncCommand : ICommand
{
    Task ExecuteAsync(object parameter);
}

public abstract class AsyncCommandBase : IAsyncCommand
{
    public abstract bool CanExecute(object parameter);
    public abstract Task ExecuteAsync(object parameter);

    public async void Execute(object parameter)
    {
        await ExecuteAsync(parameter);
    }

    public event EventHandler CanExecuteChanged;

    protected void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

public class AsyncCommand<TResult> : AsyncCommandBase, INotifyPropertyChanged
{
    private readonly Func<Task<TResult>> _command;
    private NotifyTaskCompletion<TResult> _execution;

    public AsyncCommand(Func<Task<TResult>> command)
    {
        _command = command;
    }

    public override bool CanExecute(object parameter)
    {
        return Execution == null || Execution.IsCompleted;
    }

    public override async Task ExecuteAsync(object parameter)
    {
        Execution = new NotifyTaskCompletion<TResult>(_command());
        RaiseCanExecuteChanged();
        await Execution.TaskCompletion;
        RaiseCanExecuteChanged();
    }

    public NotifyTaskCompletion<TResult> Execution
    {
        get { return _execution; }
        private set
        {
            _execution = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Теперь вы можете реорганизовать свой контроль как:

public class RippleButton : Button
{
    public static readonly BindableProperty ClickedBackgroundColorProperty =
        BindableProperty.Create(
            "ClickedBackgroundColor", typeof(Color), typeof(RippleButton),
            defaultValue: Color.FromRgb(76, 175, 80));

    public Color ClickedBackgroundColor
    {
        get { return (Color)GetValue(ClickedBackgroundColorProperty); }
        set { SetValue(ClickedBackgroundColorProperty, value); }
    }

    public static readonly BindableProperty AsyncCommandProperty =
        BindableProperty.Create(
            "AsyncCommand", typeof(IAsyncCommand), typeof(RippleButton),
            defaultValue: default(IAsyncCommand));

    public IAsyncCommand AsyncCommand
    {
        get { return (IAsyncCommand)GetValue(AsyncCommandProperty); }
        set { SetValue(AsyncCommandProperty, value); }
    }

    public RippleButton()
    {
        const int animationTime = 150;

        TextColor = Color.FromRgb(255, 255, 255);
        BackgroundColor = Color.FromRgb(255, 87, 34);

        Clicked += async (sender, e) =>
        {
            //execute command only if button is enabled.
            if (!IsEnabled)
                return;

            //continue only if command is executable, and not allow multiple click(s)
            if (AsyncCommand == null || !AsyncCommand.CanExecute(CommandParameter))
                return;

            var defaultColor = BackgroundColor;
            BackgroundColor = ClickedBackgroundColor;
            IsEnabled = false;

            await AsyncCommand.ExecuteAsync(CommandParameter);

            await this.ScaleTo(1.2, animationTime);
            await this.ScaleTo(1, animationTime);

            IsEnabled = true;
            BackgroundColor = defaultColor;
        };
    }
}

Использование образца:

XAML

<local:RippleButton Text="Download" 
                    AsyncCommand="{Binding SimulateDownloadCommand}" />

Просмотр модели

public class YourViewModel : BaseViewModel
{
    public YourViewModel()
    {
        SimulateDownloadCommand = new AsyncCommand<bool>(() => SimulateDownloadAsync());
    }

    private IAsyncCommand _downloadCommand;
    public IAsyncCommand SimulateDownloadCommand
    {
        get { return _downloadCommand; }
        private set
        {
            if (_downloadCommand != value)
            {
                _downloadCommand = value;
                OnPropertyChanged("SimulateDownloadCommand");
            }
        }
    }

    async Task<bool> SimulateDownloadAsync()
    {
        await Task.Run(() => SimulateDownload());
        return true;
    }

    void SimulateDownload()
    {
        // Simulate a 1.5 second pause
        var endTime = DateTime.Now.AddSeconds(1.5);
        while (true)
        {
            if (DateTime.Now >= endTime)
            {
                break;
            }
        }
    }
}

Изображение 174551 Изображение 174551

Ещё вопросы

Сообщество Overcoder
Наверх
Меню