我試圖建立一種行爲,禁用該按鈕並更改文本以遵循常見模式禁用按鈕來停止用戶雙擊。我需要行爲更改在命令前生效。我能以這種方式使用行爲嗎?如何在Silverlight中的命令之前觸發行爲 - 禁用雙擊?
視圖:(設置在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>
視圖模型
使用System.Windows; 使用GalaSoft.MvvmLight;使用GalaSoft.MvvmLight.Command的 ; 命名空間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;
});
}
}
}
行爲:使用System.Windows
namespace SubmitButtonBehaviorTest.Behaviors
{ ; using 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;
}
}
}
}
}
編輯:建議與禁止通過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;
}
);
編輯:我發現一個很好的解決方案,使用消息傳遞,並補充說,作爲我自己的問題的答案。
我從來沒有使用過GalaSoft MVVM,但通常你可以用一些邏輯來編寫命令的CanExecute部分,以確定是否可以執行一個命令,該命令也可以使用命令來啓用/禁用一個按鈕,具體取決於MVVM框架。我猜你需要等待,因爲異步事件正在發生。如果在您的框架中可能,可能只需在命令開始時將CanExecute設置爲false,並忘記一個行爲。 – 2010-10-20 16:21:00
好的建議...我已經將這個嘗試添加到了我的帖子中。但是,按鈕文本不會更改。我是否需要通過不同的線程發送按鈕文本更改和禁用代碼? – Aligned 2010-10-20 16:32:21