Как заставить поведение срабатывать перед командой в Silverlight - отключить двойной щелчок? - PullRequest
0 голосов
/ 20 октября 2010

Я пытаюсь построить поведение, которое отключает кнопку и изменяет текст в соответствии с общей схемой отключения кнопки, чтобы пользователь не мог дважды щелкнуть мышью.Мне нужно, чтобы изменения поведения вступили в силу перед коммандой.Могу ли я использовать поведение таким образом?

view: (установить DataContext в загруженном событии кода позади)

<Grid x:Name="LayoutRoot" Background="White">
    <Button Height="50" Width="150" Content="Save" Command="{Binding ButtonClickedCommand}" IsEnabled="{Binding IsNextButtonEnabled}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <behaviors:SubmitButtonBehavior LoadingButtonText="WAIT!!!..." IsEnabled="True" IsFinished="{Binding IsFinishedSubmitButtonBehavior}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
</Grid>

ViewModel

используя System.Windows;использование GalaSoft.MvvmLight;использование GalaSoft.MvvmLight.Command;namespace SubmitButtonBehaviorTest {открытый класс MainPageViewModel: ViewModelBase {/// /// Закрытое свойство isFinishedSubmitButtonBehavior.///
private bool isFinishedSubmitButtonBehavior;

    public bool IsFinishedSubmitButtonBehavior
    {
        get
        {
            return this.isFinishedSubmitButtonBehavior;
        }

        set
        {
            this.isFinishedSubmitButtonBehavior = value;
            this.RaisePropertyChanged("IsFinishedSubmitButtonBehavior");
        }
    }

    /// <summary>
    /// Private ButtonClickedCommand property.
    /// </summary>            
    private RelayCommand buttonClickedCommand;

    public RelayCommand ButtonClickedCommand
    {
        get
        {
            return this.buttonClickedCommand;
        }

        private set
        {
            this.buttonClickedCommand = value;
        }
    }

    public MainPageViewModel()
    {
        this.ButtonClickedCommand = new RelayCommand(
            () =>
            {
                MessageBox.Show("Clicked");
                this.IsFinishedSubmitButtonBehavior = true;
            });
    }
}

}

Поведение:

namespace SubmitButtonBehaviorTest.Behaviors

{using System.Windows;использование System.Windows.Controls;using System.Windows.Interactivity;

/// <summary>
/// Attach this behavior to disable the button on click and change the text
/// </summary>
public class SubmitButtonBehavior : TriggerAction<UIElement>
{
    /// <summary>
    /// The original button text, reset when the IsEnabled is set back.
    /// </summary>
    public string OriginalButtonText { get; set; }

    /// <summary>
    /// Gets or sets the loading button text.
    /// </summary>
    /// <value>The loading button text.</value>
    public string LoadingButtonText { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether [change button text].
    /// </summary>
    /// <value><c>true</c> if [change button text]; otherwise, <c>false</c>.</value>
    public bool ChangeButtonText { get; set; }

    /// <summary>
    /// Set this to true when the operation is finished.
    /// </summary>
    /// <value>
    ///     <c>true</c> if this instance is finished; otherwise, <c>false</c>.
    /// </value>
    public bool IsFinished
    {
        get { return (bool)GetValue(IsFinishedProperty); }
        set
        {
            SetValue(IsFinishedProperty, value);
            this.OnIsFinishedChanged();
        }
    }

    /// <summary>
    /// Called when [is finished change].
    /// </summary>
    /// <param name="value">if set to <c>true</c> [value].</param>
    private void OnIsFinishedChanged()
    {
        if (this.AssociatedObject != null && !((Button)this.AssociatedObject).IsEnabled)
        {
            ((Button)this.AssociatedObject).IsEnabled = true;
            ((Button)this.AssociatedObject).Content = this.OriginalButtonText;
        }
    }

    // Using a DependencyProperty as the backing store for IsFinished.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsFinishedProperty =
         DependencyProperty.Register("IsFinished", typeof(bool), typeof(SubmitButtonBehavior), new PropertyMetadata(false));

    /// <summary>
    /// Initializes a new instance of the <see cref="SubmitButtonBehavior"/> class.
    /// </summary>
    public SubmitButtonBehavior()
    {
        // defaults
        this.ChangeButtonText = true;
        this.LoadingButtonText = "Please Wait...";
        // AssociatedObject is empty at initialization this.originalButtonText = this.AssociatedObject.Content.ToString();
    }

    protected override void Invoke(object parameter)
    {
        if (this.IsEnabled)
        {
            Button clickedButton = ((Button)this.AssociatedObject);
            clickedButton.IsEnabled = false;
            this.OriginalButtonText = clickedButton.Content.ToString();
            if (this.ChangeButtonText)
            {
                clickedButton.Content = this.LoadingButtonText;
            }
        }
    }
}

} ​​

EDIT: предложение с отключением через CanExecute.Текст кнопки по-прежнему не меняется.Также я все еще хотел бы сделать это многоразовым поведением, но это также может быть хорошим подходом.

this.ButtonClickedCommand = new RelayCommand<Button>(
            (clickedButton) =>
            {
                string originalText = clickedButton.Content.ToString();
                this.IsSubmitting = true;
                clickedButton.Content = "Please Wait...";
                MessageBox.Show("Clicked");
                this.IsFinishedSubmitButtonBehavior = true;
                this.IsSubmitting = false;
                clickedButton.Content = originalText;
            },
            (clickedButton) =>
            {
                return !this.IsSubmitting;
            }
            );

Редактировать: я нашел хорошее решение, используя обмен сообщениями, и добавил это как ответ на мойсобственный вопрос.

Ответы [ 2 ]

0 голосов
/ 04 ноября 2010

Я нашел лучшее решение, чем поведение, используя инструментарий MvvmLight Messaging.1. создать ключ в вашем MainPage.xaml.cs 2. зарегистрировать сообщение в конструкторе, используя ключ

    GalaSoft.MvvmLight.Extras.SL4.Messenger.Default.Register<NotificationMessage>(this, 
MainPage.EnableButtonKey, message =>{                   
// send true if submitting, false if finished
          // Save or Saving is default
          this.SaveButton.IsEnabled = message.Content;

this.SaveButton.Content = message.Notification;});}));

  1. Отправьте сообщение для включения или выключения кнопки, например: Messenger.Default.Send> (new NotificationMessage (this, false, «Please Wait ...»), MainPage.SubmitKey);// повторно включаем Messenger.Default.Send> (новый NotificationMessage (this, true, originalButtonText), MainPage.SubmitKey);
0 голосов
/ 21 октября 2010

Как заметил Дэн, вам лучше использовать CanExecute для реализации логики отключения.Что касается изменения текста кнопки, я бы рекомендовал использовать привязку к this.IsSubmitting через ValueConverter, который выбирает правильный текст.Это сводит к минимуму взаимодействие между вашей ViewModel и View в том смысле, что все, что делает ViewModel, говорит, что я отправляю, и View прочитает это и отобразит правильный текст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...