This is not real code, I know. But it is what I would like to do.
MyBinding.CanExecute += (s, e) =>
{
e.CanExecute = Something.Allow;
if (!e.CanExecute)
e.ToolTip = 开发者_如何学PythonSomething.Reason;
}
Is there a simple way to do it?
Thank you.
From your question, I assume you are doing this from a ViewModel. If so, the simplest thing to do is to have an observable "CanExecute" property for your command, and another string "Reason" property for your tooltip.
Then, you listen for the PropertyChanged event within the ViewModel. When the CanExecute property changes, you simply update the reason.
Here is some sample code, which simply sets the CanExecute property to false when the command is executed:
public MyViewModel()
: base()
{
this.PropertyChanged += (s, e) =>
{
if (e.PropertyName == "SomeCommandCanExecute")
{
if (mSomeCommandCanExecute)
this.Reason = "Some Command Can Execute";
else
this.Reason = "Some Command Cannot Execute Because....";
}
};
}
private RelayCommand mSomeCommand = null;
private Boolean mSomeCommandCanExecute = true;
public RelayCommand SomeCommand
{
get
{
if (mSomeCommand == null)
{
mSomeCommand = new RelayCommand(
cmd => this.ExecuteSomeCommand(),
cmd => this.SomeCommandCanExecute);
}
return mSomeCommand;
}
}
public Boolean SomeCommandCanExecute
{
get { return mSomeCommandCanExecute; }
set { SetProperty("SomeCommandCanExecute", ref mSomeCommandCanExecute, value); }
}
private void ExecuteSomeCommand()
{
this.SomeCommandCanExecute = false;
}
private string mReason = "Some Command Can Execute";
public string Reason
{
get { return mReason; }
set { SetProperty("Reason", ref mReason, value); }
}
And then in your View:
<StackPanel>
<Button Command="{Binding SomeCommand}"
ToolTip="{Binding Reason}"
Content="Some Command"/>
<TextBlock Text="{Binding Reason}"
ToolTip="{Binding Reason}" />
</StackPanel>
Note that you won't see the ToolTip on the disabled button when CanExecute is set to false, which is why I added the TextBlock to show it. You will see the ToolTip on the TextBlock.
This is the best way I believe to accomplish this.
This is the Command definition:
class CustomCommand : RoutedUICommand, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string m_Reason;
public string Reason
{
get { return m_Reason; }
set
{
if (m_Reason == value)
return;
m_Reason = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Reason"));
}
}
}
public class MyCommands
{
public static CustomCommand DoThis = new CustomCommand();
public static CommandBinding DoThisBinding = new CommandBinding
{ Command = DoThis };
public static void SetupCommands()
{
DoThisBinding.CanExecute += (s, e) =>
{
var _Something = DoSomeTest(e.Parameter);
e.CanExecute = _Something.Allow;
if (!e.CanExecute)
(e.Command as CustomCommand).Reason = _Something.Reason;
}
}
}
And this is the XAML implementation:
xmlns:commands="MyNamespace.WhereAreCommands"
<Button Command="{x:Static commands:MyCommands.DoThis}"
ToolTip="{Binding Path=Reason,
Source={x:Static commands:MyCommands.DoThis}}">
Click</Button>
精彩评论