views:

141

answers:

1

I have a custom implementation of WPF's ICommand, that executes its bindings in a BackgroundWorker, so that the UI stays responsive.

I would like to display a custom effect while the bindings are being executed. For now, the effect is simplified to setting command source's IsEnabled property to False. Later, our designer will come up with some nice progress-style animation.

Here's an example of what I'm trying to do, that works (sort of):

<Button Width="80"
        Command="{x:Static Member=local:AppCommands.Test}"
        DataContext="{x:Static Member=local:AppCommands.Test}">
  <Button.Style>
    <Style TargetType="{x:Type Button}">
      <Setter Property="IsEnabled" Value="True"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsExecuting, Mode=OneWay}" Value="True">
          <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>

As evident, my ICommand contains an IsExecuting property, which is set to True while the BackgroundWorker does its thing with the bindings, consequently disabling the button in the UI.

Unfortunately, having to explicitly set the button's DataContext to command instance prevents me from referring to the original DataContext in cases like this one:

<Button Width="80"
        Command="{x:Static Member=local:AppCommands.ParamTest}"
        CommandParameter="{Binding Path=SelectedItem}"
        DataContext="{x:Static Member=local:AppCommands.ParamTest}">

Here, the CommandParameter should bind to the window's DataContext (which is set to an instance of my view-model), but instead it binds to the command which knows nothing about SelectedItem.

There are probably more ways to solve this, and I'm interested to hear all of them. I myself have been thinking along the lines of using an attached property to replace the direct binding to command's IsExecute and with it the need for setting the DataContext, but I'm not yet sure how to do that.

Any advice is most welcome. Thank you!

A: 

For now, I've come up with this simple solution:

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Command.IsExecuting, Mode=OneWay}" Value="True">

It does what I wanted so I'm happy. If anyone thinks there's a better way, I'm still interested, though.

aoven