Elements don't take FallbackValues (for the Style properties)

自作多情 提交于 2019-12-24 08:55:30

问题


I'm facing a problem with a UserControl development.

The UserControl exposes a couple of DPs (of the Style type). The UserControl's elements bind their's Style properties to them. In order to show something if Styles are not defined by the user, the UserControl provide FallbackValues (Styles defined in the UserControl.Resources section) for those bindings. The issue is that the only one of the UserControl's elements take the FallbackValue, the others - not. It seems like something just overrides FallbackValues. Moreover, the VS designer show the UserControl itself normally (I mean, it seems that FallbackValues are taken properly). But when the UserControl resides in the other UserControl or a Window I see the behaviour descibed previously.

Here is the xaml of the UserControl:

<UserControl
Background="White" Style="{Binding UserControlStyle}"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<UserControl.Resources>      
    <LinearGradientBrush x:Key="GeneralKeyBackground" StartPoint="0.5,0" EndPoint="0.5,1">
        <GradientStop Offset="0" Color="#FFA0A9B2" />
        <GradientStop Offset="1" Color="#FF5B626A" />            
    </LinearGradientBrush>

    <LinearGradientBrush x:Key="StationNameBackground" StartPoint="0.5,0" EndPoint="0.5,1">
        <GradientStop Offset="0" Color="#FFC4E3FF" />
        <GradientStop Offset="0.462" Color="#FFE7F3FF" />
    </LinearGradientBrush>

    <Style x:Key="DefaultStationNameForSearchingStyle" TargetType="TextBox">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid>
                        <TextBox TextAlignment="Center" Text="{TemplateBinding Text}" 
                                 Background="Transparent" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="FontSize" Value="22" />
        <Setter Property="Foreground" Value="Black" />
    </Style>

    <Style x:Key="DefaultButtonsStyle" TargetType="customControls:RoundButton">
        <Setter Property="Template" Value="{DynamicResource RoundButtonTemplate}" />
        <Setter Property="Width" Value="85" />
        <Setter Property="Height" Value="75" />          
        <Setter Property="FontFamily" Value="Verdana" />
        <Setter Property="FontSize" Value="22" />
        <Setter Property="Background" Value="{StaticResource GeneralKeyBackground}" />
        <Setter Property="Foreground" Value="White" />
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="Gray" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <DataTemplate x:Key="StationTemplate">
        <customControls:RoundButton MinWidth="350" MinHeight="60" DataContext="{Binding}" Content="{Binding }" />
    </DataTemplate>

    <Style x:Key="DefaultTitleStyle" TargetType="TextBlock">
        <Setter Property="Control.FontSize" Value="48" />        
        <Setter Property="Control.Foreground" Value="Black" />
    </Style>       

    <Style x:Key="DefaultStationNameForSearchingBorderStyle" TargetType="Border">           
        <Setter Property="BorderBrush" Value="#FF2C8BF5" />
        <Setter Property="Background" Value="{StaticResource StationNameBackground}" />
    </Style>
    <!-- EndRegion -->

</UserControl.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <TextBlock Text="Select Station"
               Style="{Binding TitleStyle, FallbackValue={StaticResource DefaultTitleStyle}}" />

    <userControls:ScrollableWrapPanel x:Name="StationsPanel" Grid.Row="1"  ItemsSource="{Binding FilteredStations}"
                                      ItemTemplate="{StaticResource StationTemplate}"
                                      ButtonsStyle="{StaticResource DefaultButtonsStyle}" />

    <Border Grid.Row="2" MinWidth="460" MinHeight="65"
            Style="{Binding StationNameForSearchingBorderStyle, FallbackValue={StaticResource DefaultStationNameForSearchingBorderStyle}}">
        <TextBox x:Name="StationName" Width="420" Height="55" SelectionChanged="TextBoxBase_OnSelectionChanged"
                 Style="{Binding StationNameForSearchingStyle, FallbackValue={StaticResource DefaultStationNameForSearchingStyle}}" />
    </Border>

    <Border Grid.Row="3" Style="{Binding KeyboardBorderStyle}">
        <virtualKeyboard:VirtualKeyboard x:Name="VirtualKeyboard" 
                         GeneralKeyStyle="{Binding KeyboardButtonsStyle, FallbackValue={StaticResource DefaultButtonsStyle}}"/>
    </Border>
</Grid>

VirtualKeyboard buttons take the FallbackValue always, it just works. The others are not. What can you advice to debug this very strange behaviour?


回答1:


The documentation for BindingBase.FallbackValue states

A binding returns a value successfully if:

  1. The path to the binding source resolves successfully.
  2. The value converter, if any, is able to convert the resulting value.
  3. The resulting value is valid for the binding target (target) property.

If 1 and 2 return DependencyProperty.UnsetValue, the target property is set to the value of the FallbackValue, if one is available.

So, if any of your DependencyProperties are being set or returning a [null] value, it will be considered a valid bind and the FallbackValue will not be used.

I do not know if this is your problem as I would need to see more of your solution, but it would be worth checking into.

I hope this helps.




回答2:


Like @EngineerSpock said in the comments above, use TargetNullValue instead.



来源:https://stackoverflow.com/questions/20811849/elements-dont-take-fallbackvalues-for-the-style-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!