App Culture 上的 WinRT XAML AppBarButton UI 样式问题已更改

WinRT XAML AppBarButton UI style issue on App Culture changed

我有两个自定义应用栏按钮,如下面的屏幕截图所示。这些按钮的样式写在 App.xaml 页面中。 app/device 语言更改后,按钮样式会变形。在比较和分析我之前准备的不同构建时,我发现在我在 App.xaml

中引入以下语言文化覆盖更改之前,这些样式工作得很好
CultureInfo ci = new CultureInfo(currentAppLanguage);
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = ci.Name;
CultureInfo.DefaultThreadCurrentCulture = ci;
CultureInfo.DefaultThreadCurrentUICulture = ci;

其中currentAppLanguage的值为App/Device对应的语言

此区域性更新很重要,因为一些控件(如 Datepicker 等)依赖此区域性更改来根据所选语言进行翻译。

错误:

正确:

该页面在英语文化下运行良好。但是当用户通过应用程序或 Phone 更新语言时,按钮样式会中断。

我在应用加载时根据所选语言覆盖主要语言区域性。文化变革是否可能影响 XAML 样式和元素?

任何建议都会有很大帮助。 提前致谢。

下面是应用栏按钮控件和样式

Button:

    <AppBarButton 
        Visibility="{Binding CanReject, Converter={StaticResource BoolToVisibilityConverter}}"
        x:Name="abReject"
        Grid.Column="3"
        Height="62"
        Width="62"
        Style="{StaticResource RejectAppBarButtonStyle}"
        IsEnabled="{Binding LoadedApproval.ApprovalState, Converter={StaticResource StringComparerToBoolConverter}, ConverterParameter=Pending}"
        BorderBrush="{StaticResource DictationGray}" 
        BorderThickness="2"
        Foreground="White"
        Background="{StaticResource ApprovalRejectRed}"
        Margin="0,0">
            <Interactivity:Interaction.Behaviors>
               <Core:EventTriggerBehavior EventName="Click">
                   <Core:GoToStateAction StateName="Rejecting" UseTransitions="True"/>
                   </Core:EventTriggerBehavior>
             </Interactivity:Interaction.Behaviors>
     </AppBarButton>

Style:

<Style x:Key="RejectAppBarButtonStyle" TargetType="AppBarButton">
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="AppBarButton" >
                <Grid x:Name="RootGrid" Background="Transparent">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ApplicationViewStates">
                            <VisualState x:Name="FullSize"/>
                            <VisualState x:Name="Compact">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="TextLabel">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="RootGrid">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="60"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <RepositionThemeAnimation TargetName="RootGrid"/>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PointOverOverlay"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <PointerDownThemeAnimation TargetName="RootGrid"/>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="OuterEllipse">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApprovalRejectRed}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused"/>
                            <VisualState x:Name="Unfocused"/>
                            <VisualState x:Name="PointerFocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Ellipse 
                        x:Name="OuterEllipse"
                        Height="{TemplateBinding Height}" 
                        Width="{TemplateBinding Width}" 
                        Stroke="{TemplateBinding BorderBrush}"
                        StrokeThickness="2" 
                        UseLayoutRounding="True">
                    </Ellipse>
                    <Grid>
                        <Ellipse 
                            x:Name="BackgroundEllipse"
                            Height="{Binding Height, Converter={StaticResource ArithmeticOperationConverter}, ConverterParameter=0.78, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                            Width="{Binding Width, Converter={StaticResource ArithmeticOperationConverter}, ConverterParameter=0.78, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                            Fill="{TemplateBinding Background}"
                            UseLayoutRounding="True">
                        </Ellipse>
                        <Ellipse 
                            x:Name="PointOverOverlay"
                            Opacity="0"
                            Height="{Binding Height, Converter={StaticResource ArithmeticOperationConverter}, ConverterParameter=0.78, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                            Width="{Binding Width, Converter={StaticResource ArithmeticOperationConverter}, ConverterParameter=0.78, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                            Fill="{StaticResource PointOverShade}"
                            UseLayoutRounding="True">
                        </Ellipse>
                        <Path 
                            x:Name="Content"
                            Data="M1.5,1.5 L40.392,40.391 M1.5,40.391 L40.392,1.5" 
                            VerticalAlignment="Center"
                            HorizontalAlignment="Center"
                            StrokeStartLineCap="Round" 
                            Stretch="Uniform" 
                            StrokeEndLineCap="Round" 
                            Stroke="{TemplateBinding Foreground}" 
                            StrokeThickness="3" 
                            StrokeLineJoin="Round" 
                            Height="{Binding Height, Converter={StaticResource ArithmeticOperationConverter}, ConverterParameter=0.33, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                            Width="{Binding Width, Converter={StaticResource ArithmeticOperationConverter}, ConverterParameter=0.33, RelativeSource={RelativeSource Mode=TemplatedParent}}">
                        </Path>
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我找到了问题发生的地方。那是在转换器 class ArithmeticOperationConverter 中。下面是转换方法。

public object Convert(object value, Type targetType, object parameter, string language)
{
    if (parameter == null)
        return value;

    Double val;
    Double param;

    if (Double.TryParse(value.ToString(), out val) && Double.TryParse(parameter.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out param))
    {
        switch (Mode)
        {
            case (ArithmeticMode.Addition):
                return val + param;
            case (ArithmeticMode.Subtratction):
                return val - param;
            case (ArithmeticMode.Multiplication):
                return val * param;
            case (ArithmeticMode.Division):
                return val / param;
            default:
                return val;
        }
    }
    else
        return value;
}

这里是 TryParse() 方法,它在条件导致问题的情况下解析参数值。传递的参数字符串值(例如)是“0.78”,结果是 78.0 而不是 0.78,导致 UI 中的失真。 发生这种情况是因为数字符号之间的文化差异。我向 TryParse() 方法添加了 CultureInfo.InvariantCulture 参数,它解决了问题。

谢谢你的建议@GraceFeng-MSFT