Two way binding does not work if binding is changed from DataTrigger

I have the following DataTemplate for my toolbox items:

<DataTemplate DataType="{x:Type viewModels:PopupContextActionViewModel}">
   <Grid>
      <ToggleButton Name="ToggleButton">
         <ContentControl Template="{Binding Icon, Converter={StaticResource NameToResourceConverter}}" Margin="5" />
      </ToggleButton>
      <Popup Name="ContextActionPopup" StaysOpen="False" AllowsTransparency="True"
         IsOpen="{Binding 
            ElementName=ToggleButton, 
            Path=IsChecked, 
            Mode=TwoWay, 
            UpdateSourceTrigger=PropertyChanged}">
         <Border Background="Transparent" Name="Border" Visibility="Visible">
            <ContentControl x:Name="ContentControl" userInterface:RegionHelper.RegionName="{Binding RegionId}" Style="{StaticResource PopupContentStyle}" />
         </Border>
      </Popup>
   </Grid>
   <DataTemplate.Triggers>
      <Trigger SourceName="ContentControl" Property="Content" Value="{x:Null}">
         <Setter TargetName="ContextActionPopup" Property="IsOpen" Value="False" />
      </Trigger>
   </DataTemplate.Triggers>

      

Everything works fine (my popup and my toggle button are working together as they should). But if I set the Trigger value of my DataTemplate (which is done by my business logic or more specific with some "NavigationService") the Popup is closed while the ToggleButton remains set.

Why isn't my trigger changing the IsChecked property of my ToggleButton?

+3


source to share


1 answer


Your answer can be found on the Dependency Property Value Priority page on MSDN. In short, you set a local value on a property IsOpen

and takes precedence over the value you set Trigger

. The solution is not to set the local value, but instead set the initial value to Style

, which has a lower priority than Trigger

.

From the linked page on MSDN:



Following is the final order that the property system uses when assigning runtime values ​​to dependency properties. Highest priority listed first. This list expands on some of the generalizations made in the overview of dependency properties.

  • Enforcement of the property system. For more information on coercion, see the Coercion, Animation, and Baseline section of this section.

  • Active animations or animations with Hold behavior. To have any practical effect, object animations must be able to take precedence over the base (non-stackable) value, even if this value was set locally. See the Coercion, Animation, and Baseline section later in this section for details.

  • Local value. The local value can be set through the convenience of the "wrapper" property, which is also the same as setting as an attribute or element of a property in XAML, or by calling the SetValue API using a specific instance property. If you set a local value using bindings or a resource, each one acts in precedence as if it were the direct value it was set.

  • Properties of the TemplatedParent template. An element has a TemplatedParent if it was created as part of a template (a ControlTemplate or DataTemplate). See TemplatedParent later in this section for details on when this is applicable. Within the template, the following priority applies:

a.Triggers from TemplatedParent template.

b. Sets of properties (usually via XAML attributes) in the TemplatedParent template.

  1. Implicit style. Applies only to the Style property. The Style property is populated with any style resource using a key that matches the type of that element. This style resource must exist in either the page or the application; search for an implicit style resource don't go to those.

  2. Style triggers. Triggers on styles from the page or application (these styles can be either explicit or implicit, but not from the default styles, which have a lower priority).

  3. Template triggers. Any trigger from a template-to-style or directly applied template.

  4. Customizing styles. Values ​​from a setter in styles from a page or app.

  5. Default style (theme). For more information on when applicable and how theme styles relate to templates in theme styles, see Default (Theme) Styles in this theme. The default style applies the following order of precedence:

a. Active triggers in theme style.

b. Creates a theme style.

  1. Inheritance. Several dependency properties inherit their values ​​from parent to child, so they don't need to be set especially for every element in the application. For more information, see Property Value Inheritance.

  2. The default value from the metadata of the dependency properties. Any given dependency property can have a default value set by the ownership system registration of that particular property. Also, derived classes that inherit the dependency property have the ability to override this metadata (including the default) for each framework type. For more information, see Dependency Property Metadata. Because inheritance is checked before the default value for an inherited property, the default value for the parent element takes precedence over the child element. Hence, if an inherited property is not set anywhere, the default value specified in the root or parent of the default child is used instead.

+1


source







All Articles