views:

326

answers:

3

I've a custom SplitButton implementation in which contains a ComboBox with several ComboBoxItems bound to commands. I can bind to the Name, and Text properties of the command just fine but have no way of binding the ComboBoxItem's IsEnabled property to the result of a Command's CanExecute method because it is a method. Is there some syntax that I'm unaware of for binding to methods or is there some trickery that will help me to bind to CanExecute.

By the way, I've thought about using a custom ValueConverter except for that I realized that I probably wouldn't receive any updates when CanExecute is re-evaluated since it is not a property and since my commands are not business objects. It's looking to me that I might have to create a ViewModel for a command at this point to use only within my custom SplitButton control but that seems a little overboard to me.

+1  A: 

You can put a button(if you dont have one in the controltemplate bound to the ICommand) inside ItemContainerStyle(ComboBoxItem style) and Bind the command to it And add a Trigger to check the Button.IsEnabled and set that value to the ComboBoxItem. So here we used Button as a CommandSource just to get the IsEnabled from CanExeute. You can set the button's height and width to zero

 <ControlTemplate....>
   <Grid ...
       <Button x:Name="dummyButton" Command="{Binding YourCommand}" ....
           ......
   </Grid>

   <ControlTemplate.Triggers>
      <Trigger SourceName="dummyButton" Property="IsEnabled" Value="False">
        <Setter Property="IsEnabled" Value="False"/>
      </Trigger>
   </ControlTemplate.Triggers>
Jobi Joy
Neat, I think this definitely falls under the trickery category but I like it. If nobody comes up with anything more elegant I'll use this.
jpierson
Yes ofcourse this is tricky so as your requirement too. The proper way to do is to add bool ViewModel property, If you want to do a ICommand.CanExecute to a DependancyProperty binding this is the best way I can see
Jobi Joy
I agree, I think my comment may have come off the wrong way. In the end I couldn't really use the dummy Button concept because I'm declaring my ComboBoxItems and would need a button. With nowhere convenient to place my dummy buttons I opted for a different solution.
jpierson
Oh if you have a button then, dont add another dummy button. I assumed you dont have button inside it.
Jobi Joy
A: 

Another solution by ViewModel. Below is how I used a ViewModel to solve my problem. And please note that the nifty NotifyPropertyChanged method is part of my base ViewModel class.

public class RoutedUICommandViewModel : ViewModel
{
    private RoutedUICommand _command;
    private IInputElement _target;

    public string Name { get { return _command.Name; } }

    public string Text { get { return _command.Text; } }

    public bool CanExecute
    {
        get
        {
            return _command.CanExecute(null, _target);
        }
    }

    public RoutedUICommand Command { get { return _command; } }

    public RoutedUICommandViewModel(ReportCommand command, IInputElement target)
    {
        _command = command;
        _target = target;
        _command.CanExecuteChanged += _command_CanExecuteChanged;
    }

    private void _command_CanExecuteChanged(object sender, EventArgs e)
    {
        base.NotifyPropertyChanged(() => this.CanExecute);
    }
}
jpierson
I've accepted this answer only because it is currently what I decided to use in my case. The other solutions are acceptable though and I'll plan to up-vote any of these other solutions too.
jpierson
A: 

I found this discussion on MSDN forums where Dr. WPF had recommended the use of an attached behavior to solve this exact problem. He gave the example below of how it would be used.

<Grid behaviors:CommandBehaviors.EnablingCommand="{x:Static commands:testcommand.test}">  
  . . .  
</Grid> 

Although this solution seems pretty nice I haven't been able to devote the time to understand exactly how this type of behavior would be implemented and what is involved. If anybody would like to elaborate please do otherwise I'll amend this answer with more details if I get the chance to explore this option.

jpierson