xamldatatriggerdynamicresource

Using DynamicResource Style and DataTrigger for button in XAML


I am using predefined style like Style="{DynamicResource SquareButtonStyle}"

that cannot be modified and I need to enable/disable a Button via DataTrigger.

It seems like is impossible to do?

The error is: The property 'Style' is set more than once.

<Button Content="Guardar" Width="100"  Style="{DynamicResource SquareButtonStyle}" Name="SaveTemplateATM" Click="SaveTemplateATM_Click">
  <Button.Style>
        <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                       <DataTrigger Binding="{Binding Text.Length, ElementName=UserName, UpdateSourceTrigger=PropertyChanged}" Value="0">
                           <Setter Property="IsEnabled" Value="False"/>
                       </DataTrigger>                                           
             </Style.Triggers>
        </Style>
  </Button.Style>
</Button>

Solution

  • You can only set the style attribute (or any attribute) once, but you can set it to a new style that is based on the resource style. That means it'll inherit everything that resource style has, plus it'll have whatever you add yourself.

    <Button Content="Guardar" Width="100" Name="SaveTemplateATM" Click="SaveTemplateATM_Click">
        <Button.Style>
            <Style 
                TargetType="{x:Type Button}" 
                BasedOn="{StaticResource SquareButtonStyle}"
                >
                <Style.Triggers>
                    <DataTrigger 
                        Binding="{Binding Text.Length, ElementName=UserName}" 
                        Value="0"
                        >
                        <Setter 
                            Property="IsEnabled" 
                            Value="False"
                            />
                    </DataTrigger>                                           
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    

    Also, UpdateSourceTrigger=PropertyChanged is at best harmless here, but you don't want it on that binding. What that flag does is to tell the Binding how to update the source property for the binding (that's UserName.Text.Length in this case), when the target property changes (that's Button.IsEnabled in this case). That doesn't make sense here: Even if UserName.Text.Length weren't read-only, that Binding would never update it and you wouldn't want it to.

    The UpdateSourceTrigger flags are for modifying the default behavior of two-way bindings, for example if you were binding the Text property of a TextBox to a viewmodel string property, the default behavior is to update the viewmodel property when the TextBox loses focus. You might want it to update every time the user types a character instead -- in which case you'd give the Binding UpdateSourceTrigger=PropertyChanged.