views:

503

answers:

2

I have the following dependency property:

public bool IterationSelected
{
    get { return (bool)GetValue(IterationSelectedProperty); }
    set { SetValue(IterationSelectedProperty, value); }
}
public static readonly DependencyProperty IterationSelectedProperty =
  DependencyProperty.Register("IterationSelected", typeof(bool),
  typeof(MainMediator), new UIPropertyMetadata(false));

(this was generated from the VS template)

I then have this trigger that updates it:

<Grid.Style>
    <Style>
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource IsOpenFalseAndIsCheckedTrueMultiConverter}">
                        <Binding ElementName="popSelectIteration" Path="IsOpen"/>
                        <Binding ElementName="chkIteration" Path="IsChecked"/>
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="loc:MainMediator.IterationSelected" Value="True"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Grid.Style>

Lastly, I have this Grid that has its visibility dependent on the property.

<Grid Visibility="{Binding IterationSelected, Converter={StaticResource BooleanToVisibilityConverter}, diagnostics:PresentationTraceSources.TraceLevel=High}" Grid.Row="1">
    <TextBlock>Testing 1323</TextBlock>
</Grid>

So, here is the problem, I have used: diagnostics:PresentationTraceSources.TraceLevel="High" to test all the bindings and everything works fine except that when loc:MainMediator:IterationSelected gets set to true, the Grid does not pickup on it. Nothing fires at all. It is not that it can't bind or anything like that. It just does not even try. The only time the grid binding fires is at start of the app. It fires and evaluates correctly at that time.

The only thing I have tried (and failed at) was making IterationSelected an attached property instead of a plain dependency property. However, that failed too.

WPF Gurus, any ideas?

+1  A: 

It's a bit hard to tell, but it looks like your binding source is wrong. There also seems to be some ambiguity about the property reference but that may be an artefact of the attached property experiment.

Basically your Grid.Visibility binding is looking for an IterationSelected property on the current DataContext. But your Style DataTrigger is setting the loc:MainMediator.IterationSelected property on the Grid.

The fix for this would be to make your Grid.Visibility binding look for a loc:MainMediator.IterationSelected property on the Grid itself (rather than on the DataContext). To do this, add RelativeSource={RelativeSource Self} to the binding declaration:

Visibility="{Binding IterationSelected,
                     Converter={StaticResource BooleanToVisibilityConverter},
                     RelativeSource={RelativeSource Self}}">

This tells the binding to look at the element it is bound to rather than at the DataContext.

You may also need to change the path to be loc:MainMediator.IterationSelected rather than just IterationSelected.

Finally, depending on whether the IterationSelected property is doing any other jobs, an alternative approach is just to have your Setter set the Visibility directly:

<DataTrigger Value="True">
  <!-- binding omitted -->
  <Setter Property="Visibility" Value="Visible" />
</DataTrigger>
itowlson
+1  A: 

The Setter in your sample is trying to set the IterationSelected property on the Grid but the DP is owned by the MainMediator type. Were you intending to set the value on a MainMediator and if so, where is it in relation to the Grid? It looks like you may actually want to apply this Style to a MainMediator control instead but I can't quite tell from this code. You also mentioned trying an AP, which would allow you to set IterationSelected on a Grid.

Can you give some more context on what you're intending to happen?

John Bowen