0

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

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

问题示例

<DataTemplate x:Key="ToggleSwitchTextBlockTemplate">
    <TextBlock
        TextWrapping="Wrap"
        Text="{Binding}"
        HorizontalAlignment="Stretch" />
</DataTemplate>

<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}"
    Width="200" />

如何强制 Off/OnContent 包装并适合 ToggleSwitch 边界?

期望的结果,其中 Off/OnContent 被包装

4

2 回答 2

0

在 ToggleSwitch 的样式中,有 OffContentPresenter 和 OnContentPresenter 代表 OffContent 和 OnContent,你可以添加 TextWrapping 来包裹内容并设置 Width 来限制它的宽度。关于完整的样式,可以去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>

更新:

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

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

<Grid HorizontalAlignment="Left" MinWidth="{StaticResource ToggleSwitchThemeMinWidth}" Grid.Row="1" VerticalAlignment="Top">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition MaxWidth="12" Width="12"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    ......
</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" />
于 2019-12-16T02:14:35.593 回答
0

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

        <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>

ToggleSwitch 的宽度为 200。但 OffContent 的 TextBlock 的宽度为“Auto (246.224)”。就像在我的示例中,它远远超出了父元素。结果它不会按预期包装。

我对此的看法,这是 ToggleSwitch 行为中的一个错误。ToggleSwitch 应该安排其子项的布局。例如,如果 ToggleSwitch 元素的 Width 为 200,则将 40 分配给 Toggle,将 160 分配给 OffContent/OnContent。这只是关于如何实施的理论,而不是实际数字。由于 OffContent/OnContent 几乎总是一个简短的词(“Off/On”或“No/Yes”)并且不跨越多行,Microsoft 从未测试过这个测试用例。

于 2020-01-13T19:12:55.160 回答