I used RelayCommand
of MVVM Foundation, now, when I try to use the "normal" ICommand
, I don't really get how to use it, particularly "binding" it to variables used my my main class. I am just wanting to create a OkCommand
that raises an event (RequestClose
) in the main class,开发者_如何学JAVA view model. Also, I want to enable it only if all bindings are valid. Validations are implemented using ValidationRule
, something like below
<TextBox>
<TextBox.Text>
<Binding Path="Blue">
<Binding.ValidationRules>
<validators:ByteValidator />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
ICommand
is an interface, so it's inherently abstract. You can't use it directly - you need something that implements it. (E.g. RelayCommand
)
WPF does provide a built in implementation of ICommand
: RoutedCommand
. (And a related derived type, RoutedUICommand
.) However, these types are designed for a very specific scenario that doesn't match what you describe. (They use the structure of the UI tree to work out what will handle the command. This is usually only appropriate where you have multiple different implementations of some common command provided directly by controls. E.g., TextBox knows how to implement Cut, Copy, Paste, etc, and you want the TextBox that has the focus to handle the command.)
So there isn't really a "normal" ICommand
implementation. And also, you probably don't want to use validation rules...
Validation rules are pretty limited, and it's very difficult to get them to support the scenario you describe. They have two limitations:
- They're really only good for completely self-contained validation rules that can be applied without needing any context. (E.g. "Is this string a decimal number?")
- It's hard to connect them with anything else, because the whole mechanism has no concept of context.
That second one makes it hard to do what you want. This is why they don't get used a whole lot, which is presumably why Microsoft introduced a better mechanism - for most validation scenarios, you don't use ValidationRule, and instead you make your data source implement IDataErrorInfo.
The principle is that it's your data source object that gets to decide whether it's valid or not. And your data source object can then also modify the validity of any commands. That's how you would arrange for the OkCommand object to be disabled when items are invalid.
And since WPF doesn't provide a simple built-in implementation of ICommand that suits this scenario, that's why people feel the need to write things like RelayCommand
. It's a response to the fact that WPF doesn't really have a built-in "normal" command - it only has the funky routed commands.
精彩评论