WPF以拉伸标签固定宽度为中心文本

时间:2016-06-16 08:16:12

标签: wpf xaml width pixel centering

我的目标是简单,但我无法理解。对不起标题,但无法提出更好的解释...

我有一个带有标签的usercontrol,显示当前时间(连接到1秒间隔的计时器)。标签是其父级的宽度,文本在中心对齐。格式为DateTime.ToString(“HH:mm:ss”),FontFamily和大小可由用户调整。到目前为止没有什么奇怪的...但是,文本对齐居中,所以当时间让我们说12:34:02像素宽度不同于12:34:11。 (当然取决于字体)这会导致标签跳转(因为它自动居中)

以下代码就是一个例子。画布用于在其上绘制内容并使用视图框,因此它会在其父级中自动进行自动调整。

代码:

 <Grid>
    <Viewbox>
        <Canvas Name="canv" Height="300" Width="300">
            <StackPanel Name="stckpnlDateTime">

                <Label Name="lblDateOrText" 
                       Grid.Column="0"
                       Grid.Row="0"
                       Content = "------" 
                       FontSize="25"
                       Foreground="GhostWhite"
                       HorizontalContentAlignment="Center"
                       VerticalAlignment="Bottom"
                       FontFamily="Arial"
                       Width="Auto"/>

                <Label Name="lblTime"
                       Grid.Column="0"
                       Grid.Row="1"
                       Content = "-- : -- : --"
                       FontSize="25"
                       Foreground="GhostWhite"
                       HorizontalContentAlignment="Center"
                       VerticalAlignment="Top"
                       FontFamily="DS-Digital"
                       Width="Auto"/>
            </StackPanel>                
        </Canvas>
    </Viewbox>
</Grid>

Private Sub SystemTime_Tick(sender As Object, e As EventArgs) Handles tmrSystemTime.Tick
    lblTime.Content = Now.ToString("HH : mm : ss")
End Sub

所以我尝试了一种不同的方法,一个包含10列和8个标签的网格,每个字符一个,并将标签拉伸到其父级(单元格)。这样可以将字符保持在固定位置。但是最后一列的宽度小于其余的......在这张图片中你可以看到帽子我的意思是,第二列是我的意思。 Example alignment

代码:

 <UserControl.Resources>
    <Style x:Key="LabelStyle" TargetType="Label">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="FontFamily" Value="DS-Digital" />
        <Setter Property="FontSize" Value="40"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="HorizontalContentAlignment" Value="Right"/>
        <Setter Property="Background" Value="Green" />
    </Style>
</UserControl.Resources>

<Grid HorizontalAlignment="Stretch">
    <Viewbox HorizontalAlignment="Stretch">
        <Canvas Name="canv" Height="300" Width="300" HorizontalAlignment="Stretch">
            <StackPanel Name="stckpnlDateTime" HorizontalAlignment="Stretch">                    
                <Label Name="lblDateOrText" 
                       Grid.Column="0"
                       Grid.Row="0"
                       Content = "" 
                       FontSize="25"
                       Foreground="GhostWhite"
                       HorizontalContentAlignment="Center"
                       VerticalAlignment="Bottom"
                       FontFamily="Arial"
                       Width="Auto"/>

                <Grid Name="GridTimeLabel" HorizontalAlignment="Stretch"  Width="Auto" Grid.Column="0" Grid.Row="1">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                    </Grid.ColumnDefinitions>


                    <Label Background="Purple" Grid.Column="0" Grid.Row="0"/>
                    <Label Name="lblTime1" Grid.Column="1" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
                    <Label Name="lblTime2" Grid.Column="2" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
                    <Label Name="lblTime3" Grid.Column="3" Grid.Row="0" Style="{StaticResource LabelStyle}" Content=":"/>
                    <Label Name="lblTime4" Grid.Column="4" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
                    <Label Name="lblTime5" Grid.Column="5" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
                    <Label Name="lblTime6" Grid.Column="6" Grid.Row="0" Style="{StaticResource LabelStyle}" Content=":"/>
                    <Label Name="lblTime7" Grid.Column="7" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
                    <Label Name="lblTime8" Grid.Column="8" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
                    <Label Background="Purple" Grid.Column="9" Grid.Row="0"/>
                </Grid>                 
            </StackPanel>                
        </Canvas>
    </Viewbox>
</Grid>

长话短说,我是stuk ....希望有人可以指出我正确的方向。

3 个答案:

答案 0 :(得分:0)

我有两种方法。

第一种方法: 更改为等宽字体,这将确保无论您抛出什么时间值,宽度都将保持不变。但是,您可能无法使用此方法找到合适/合适的字体。

第二种方法: 如果你没有使用MVVM,试试这个(C#代码,我不习惯VB.net):

// Code-behind
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    var label = this.lblTime;
    label.Text = "00:00:00";
    label.Measure(); // Force it to measure
    label.Width = label.DesiredSize.Width;
}

这会强制宽度保持不变。根据字体的不同,您需要手动设置占用最多空间的时间值。

另外,为了确保它正常工作,您可能需要将Label包装在Grid中。使网格有3列,在第1列(中间列)中设置标签,并将columndefinitions的宽度分别设置为*auto*

答案 1 :(得分:0)

你的画布宽度为300.我认为它的可用性不到300像素。这就是最后一栏较小的原因。

答案 2 :(得分:0)

@Jai,谢谢你指点我.Measure() Sub的方向。摆弄后我最终得到3列网格,用新内容测量标签的大小,设置标签的大小。这会导致列重新对齐,从而保留标签。

代码:(为测试创建新的WPF程序,颜色是看孩子和父母之间的区别)

    <Grid Background="Tomato">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <Label Name="lblTime"
                   Grid.Column="1"
                   Grid.Row="0"
                   Content = "-- : -- : --"
                   FontSize="50"
                   Foreground="Black"
                   Background="Beige"
                   HorizontalContentAlignment="Left"
                   VerticalAlignment="Center"
                   FontFamily="DS-Digital"/>
</Grid>

背后的代码:

Class MainWindow

''' <summary>
''' Timer for updating the time Clock
''' </summary>
Dim WithEvents tmrSystemTime As New DispatcherTimer With {.Interval = TimeSpan.FromSeconds(1)} 'Set Timer interval on every second.

Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    tmrSystemTime.Start()
End Sub

Private Sub SystemTime_Tick(sender As Object, e As EventArgs) Handles tmrSystemTime.Tick
    'Set the time in the label
    lblTime.Content = Now.ToString("HH : mm : ss")

    'Measure and set the size of the label
    MeasureSizeTimeLabel()
End Sub

''' <summary>
''' Measure the Max Size of the label with a specific Format
''' </summary>
Private Sub MeasureSizeTimeLabel()

    'Store the Max size of the Time Label in this variable
    Dim MaxClockSize As Size

    'Measure the Max size of the clock label and use this width
    'lblTime.Content = "00 : 00 : 00"
    lblTime.Measure(New Size(Double.PositiveInfinity, Double.PositiveInfinity))
    MaxClockSize = lblTime.DesiredSize

    'Now Set the size of the label
    lblTime.Width = MaxClockSize.Width
    lblTime.Height = MaxClockSize.Height
End Sub

感谢大家的帮助,感谢您的努力和时间! : - )