2016-06-16 14 views
0

내 목표는 simpel이지만 알아낼 수는 없습니다. Titel에 대한 미안하지만 더 나은 설명을 생각해 낼 수 없었습니다 ...WPF 가운데 맞춤 텍스트가 늘어난 라벨로 고정 폭

나는 현재 시간을 표시하는 레이블 (1 초 간격의 타이머에 연결됨)이있는 usercontrol을가집니다. 라벨은 부모의 너비이며 텍스트는 중앙에 정렬됩니다. 형식은 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 해요 .... 희망 누군가가 올바른 방향으로 날 지점 수 있습니다.

+0

고정 폭 글꼴을 사용할 수 없습니까? – Jai

+0

그는 폰트가 사용자에 의해 조정될 수 있다고 말합니다 – GenericTeaCup

+0

속도가 너무 빠르다고 생각합니다 ... – Jai

답변

0

@Jai, .Measure() Sub의 방향으로 나를 가리켜 주셔서 감사합니다. 주위에 바이올린을 치고 나면 3 열 그리드로 끝나고 새 콘텐트로 레이블의 크기를 측정하고 레이블의 크기를 설정합니다. 이렇게하면 열을 재정렬하여 레이블을 제자리에 유지합니다.

코드는 :

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

그리고 그 뒤에 코드를 (테스트를위한 새로운 WPF 프로그램을 만들어, 색상은 자녀와 부모 사이의 차이를 볼 수 있습니다) :

클래스 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 

도움을 주신 모든 분들께 감사드립니다. :-)

+0

실제로 Loaded 이벤트에서 또는 생성자에서 수행 할 수 있습니다. 생성자에 대해서는 컨트롤이 준비되었는지 확실하지 않습니다. 그러나 측정을 강요하고 있기 때문에 어느 쪽이든 상관 없습니다. 타이머를 사용하면 조정 전에 눈에 띄는 지연이 발생할 수 있습니다. – Jai

0

나는 두 가지 방법을 염두에두고 있습니다.

첫 번째 방법 : 모노 스페이스 글꼴로 변경하면 어떤 시간 값을 던져도 그 폭은 일정 해집니다. 그러나이 방법을 사용하여 좋은/적절한 글꼴을 찾을 수는 없습니다.

두 번째 방법 : 당신이 MVVM을 사용하지 않는 경우 는이 (내가 너무 VB.net에 익숙하지 않아요 C# 코드를) 시도는 :

// 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; 
} 

이 일정하게 유지하기 위해 폭을 강제적으로합니다. 글꼴에 따라 가장 많은 공간을 차지하는 시간 값을 수동으로 설정해야합니다.

또한 제대로 작동하는지 확인하려면 레이블을 격자에 포장해야 할 수 있습니다. 눈금에 3 개의 열이 있고 열 1 (중간 열)에 레이블이 설정되고 열 정의의 너비가 각각 *, auto* 순으로 지정됩니다.

+0

답장을 보내 주셔서 감사합니다. 방법 2는 사용자가 다른 글꼴을 사용할 수 있기를 원합니다. 그러나 OnApplyTemplate usercontrol (나를 위해 상황입니다)에서 발생하지 않습니다 – Gforse

0

캔버스의 너비는 300입니다. 사용 가능한 300px 미만이므로 캔버스가 보입니다. 이것이 마지막 열이 더 작은 이유입니다.

+0

죄송합니다, 런타임 중에 캔버스 너비는 부모의 너비로 설정되어 있다고 깜빡 했군. 이 옆에있는 열은 모두 "1 *"이며 동일한 폭을 나타냅니다. – Gforse