如何在UWP中包装切换开关的内容/OnContent?

如何在UWP中包装切换开关的内容/OnContent?,uwp,uwp-xaml,toggleswitch,Uwp,Uwp Xaml,Toggleswitch,自定义切换开关中的OffContent/OnContent不适合一行,因为它具有自定义文本,并且网格(放置切换开关的位置)中的单元格不够宽 即使我为OffContentTemplate和OnContentTemplate定义自定义模板,Off/OnContent也会超出ToggleSwitch元素的边界 如何强制关闭/打开内容以包装和适应切换开关边界 在ToggleSwitch样式中,有OffContentPresenter和OnContentPresenter表示OffContent和O

自定义切换开关中的OffContent/OnContent不适合一行,因为它具有自定义文本,并且网格(放置切换开关的位置)中的单元格不够宽

即使我为OffContentTemplate和OnContentTemplate定义自定义模板,Off/OnContent也会超出ToggleSwitch元素的边界


如何强制关闭/打开内容以包装和适应切换开关边界


在ToggleSwitch样式中,有OffContentPresenter和OnContentPresenter表示OffContent和OnContent,您可以添加文本包装来包装内容,并设置宽度来限制其宽度。关于完整样式,可以转到generic.xaml复制它

.xaml:

       <Style x:Key="ToggleSwitchStyle1" TargetType="ToggleSwitch">
            ......
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleSwitch">
                        <Grid Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                ......
                            </VisualStateManager.VisualStateGroups>
                            <ContentPresenter x:Name="HeaderContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource ToggleSwitchHeaderForeground}" IsHitTestVisible="False" Margin="{ThemeResource ToggleSwitchTopHeaderMargin}" Grid.Row="0" TextWrapping="Wrap" VerticalAlignment="Top" Visibility="Collapsed" x:DeferLoadStrategy="Lazy"/>
                            <Grid HorizontalAlignment="Left" MinWidth="{StaticResource ToggleSwitchThemeMinWidth}" Grid.Row="1" VerticalAlignment="Top">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition MaxWidth="12" Width="12"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="{ThemeResource ToggleSwitchPreContentMargin}"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="{ThemeResource ToggleSwitchPostContentMargin}"/>
                                </Grid.RowDefinitions>
                                <Grid x:Name="SwitchAreaGrid" Background="{ThemeResource ToggleSwitchContainerBackground}" Grid.ColumnSpan="3" Control.IsTemplateFocusTarget="True" Margin="0,5" Grid.RowSpan="3"/>
                                <ContentPresenter TextWrapping="Wrap" Width="100" x:Name="OffContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding OffContentTemplate}" Content="{TemplateBinding OffContent}" Grid.Column="2" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Opacity="0" Grid.RowSpan="3" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                <ContentPresenter TextWrapping="Wrap" Width="100" x:Name="OnContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding OnContentTemplate}" Content="{TemplateBinding OnContent}" Grid.Column="2" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Opacity="0" Grid.RowSpan="3" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                ......

                            </Grid>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

......
......
......
或者您也可以在ToggleSwitch的OnContent和OffContent属性中放置一个TextBlock来实现它

<ToggleSwitch Width="200" Grid.Row="2" Grid.Column="0" x:Name="SomeToggle" 
              Header="Some header" >
    <ToggleSwitch.OffContent>
        <TextBlock Width="100" TextWrapping="Wrap">Off content to verify if string is wrapped</TextBlock>
    </ToggleSwitch.OffContent>
</ToggleSwitch>

关闭内容以验证字符串是否已包装
更新:

如果不想将宽度设置为直接限制其宽度,可以将ColumnDefinition从“Auto”更改为“*”。“自动”意味着一列的宽度与其中的元素所需的宽度相同。但是“*”是基于剩余空间的宽度。因此,当您将ColumnDefinition设置为“*”时,它将根据剩余空间放置文本,如果空间不够,它将对文本进行换行

需要修改的样式部分是(您只需要从原始样式更改以下部分):


......
用法:

<ToggleSwitch
    Grid.Row="2"
    Grid.Column="0"
    x:Name="SomeToggle"
    Header="Some header"
    OffContent="Off content to verify if string is wrapped"
    OnContent="On content to verify if string is wrapped"
    OffContentTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
    OnContentTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
    Style="{StaticResource ToggleSwitchStyle1}"
    Width="200" />

我按照费旺的建议做了所有的事情,但没有任何结果。 我注意到,当我直接设置内容(而不是定义模板)并检查元素的属性时

        <ToggleSwitch
            Grid.Row="2"
            Grid.Column="0"
            x:Name="SomeToggle"
            Header="Some header"
            HeaderTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
            OnContent="On content to verify if string is wrapped"
            OnContentTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
            Width="200">
            <ToggleSwitch.OffContent>
                <TextBlock
                    Width="Auto"
                    TextWrapping="Wrap"
                    Text="Off content to verify if string is wrapped" />
            </ToggleSwitch.OffContent>
        </ToggleSwitch>

开关的宽度为200。但OffContent的文本块的宽度是“自动(246.224)”。就像在我的示例中,它远远超出父元素的范围。因此,它不会像预期的那样包装

我的看法是,这是切换开关行为中的一个错误。ToggleSwitch应该安排其子项的布局。比方说,若ToggleSwitch元素的宽度为200,则为Toggle指定40,为OffContent/OnContent指定160。这只是一个如何实施的理论,而不是实际数字。
由于OffContent/OnContent几乎总是一个简短的单词(“Off/On”或“No/Yes”),并且不跨多行,因此Microsoft从未测试过此测试用例。

这两个示例都依赖于[Width=“100”]。它没有在正确的位置结束/结束内容,而是硬编码的100宽度。这篇文章有一个主题。Off/OnContent的大小超过了ToggleSwitch的大小,这就是它没有被包装的原因。如果我使用硬编码的100值,我可以很容易地在原始文章中使用带有TextBlock的自定义DataTemplate。第0列的宽度已经设置为200。若你们看上面的例子,WidthToggleSwitch元素已经在网格的列宽内。关闭/打开内容超出了ToggleSwitch和Grid的边界。
<ToggleSwitch
    Grid.Row="2"
    Grid.Column="0"
    x:Name="SomeToggle"
    Header="Some header"
    OffContent="Off content to verify if string is wrapped"
    OnContent="On content to verify if string is wrapped"
    OffContentTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
    OnContentTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
    Style="{StaticResource ToggleSwitchStyle1}"
    Width="200" />
        <ToggleSwitch
            Grid.Row="2"
            Grid.Column="0"
            x:Name="SomeToggle"
            Header="Some header"
            HeaderTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
            OnContent="On content to verify if string is wrapped"
            OnContentTemplate="{StaticResource ToggleSwitchTextBlockTemplate}"
            Width="200">
            <ToggleSwitch.OffContent>
                <TextBlock
                    Width="Auto"
                    TextWrapping="Wrap"
                    Text="Off content to verify if string is wrapped" />
            </ToggleSwitch.OffContent>
        </ToggleSwitch>