문제

다음 스 니펫 :

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <StackPanel Orientation="Horizontal"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center">            
            <Label Content="Name:"/>
            <Label Content="Itzhak Perlman" FontSize="44"/>
        </StackPanel>
    </Grid>
</Window>

다음을 렌더링합니다.
alt text

라벨 스타일을 설정하여 텍스트 하단을 정렬 해야하는 방법이 있습니까?
TextBlock과 같은 질문도 있습니다.

참고 :이 문제로 한동안 어려움을 겪고 있기 때문에 그 일을 알고 있다는 특정 답변 만 게시하십시오.
나는 이미 시도했다 : 수직 정렬, verticalContentalIngment, 패딩, 마진. 내가 알지 못하는 다른 것이 있습니까?

나는 읽었다 이것 게시물이지만 다른 글꼴 크기의 시나리오에 대해서는 이야기하지 않습니다.

업데이트: 문제는 패딩조차도 0으로 설정되어 있다는 것입니다. 콘텐츠 프레 센터 영역 내에 글꼴 주변에 불확실한 공간이 여전히 있다는 것입니다. 이 공간은 글꼴 크기에 따라 다릅니다. 이 공간을 통제 할 수 있다면 더 나은 상황에 처할 것입니다.

감사

도움이 되었습니까?

해결책

XAML 전용 솔루션이 없으므로 코드를 사용해야합니다. 또한 Code-Behind를 사용하더라도 이에 대한 일반적인 해결책은 없습니다. 텍스트가 멀티 라인이라면 어떨까요? 이 경우 어떤 기준선을 사용해야합니까? 아니면 템플릿에 여러 텍스트 요소가 있으면 어떻게됩니까? 헤더 및 컨텐츠 또는 그 이상과 같은 기준선과 같은?

요컨대, 가장 좋은 방법은 상단/하단 마진을 사용하여 수동으로 텍스트를 정렬하는 것입니다.

단일 텍스트 요소가 있다고 가정하면 기준선의 픽셀 거리를 인스턴스화하여 요소의 상단에서 파악할 수 있습니다. FormattedText 기존 텍스트 요소와 동일한 속성을 가진 객체. 그만큼 FormattedText 물체에는 a가 있습니다 double Baseline 그 가치를 보유한 속성. 요소가 컨테이너의 상단 또는 하단에 정확하게 앉아 있지 않을 수 있으므로 여전히 수동으로 마진을 입력해야합니다.

이 MSDN 포럼 게시물을 참조하십시오. 텍스트 상자 기준선

다음은 그 값을 추출하는 방법입니다. 단일 기본 클래스에 공통적이지 않기 때문에 관련 속성을 얻기 위해 반사를 사용합니다 (별도로 정의됩니다. Control, TextBlock, Page, TextElement 그리고 아마도 다른 사람들).

public double CalculateBaseline(object textObject)
{
    double r = double.NaN;
    if (textObject == null) return r;

    Type t = textObject.GetType();
    BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;

    var fontSizeFI = t.GetProperty("FontSize", bindingFlags);
    if (fontSizeFI == null) return r;
    var fontFamilyFI = t.GetProperty("FontFamily", bindingFlags);
    var fontStyleFI = t.GetProperty("FontStyle", bindingFlags);
    var fontWeightFI = t.GetProperty("FontWeight", bindingFlags);
    var fontStretchFI = t.GetProperty("FontStretch", bindingFlags);

    var fontSize = (double)fontSizeFI.GetValue(textObject, null);
    var fontFamily = (FontFamily)fontFamilyFI.GetValue(textObject, null);
    var fontStyle = (FontStyle)fontStyleFI.GetValue(textObject, null);
    var fontWeight = (FontWeight)fontWeightFI.GetValue(textObject, null);
    var fontStretch = (FontStretch)fontStretchFI.GetValue(textObject, null);

    var typeFace = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);

    var formattedText = new FormattedText(
        "W", 
        CultureInfo.CurrentCulture, 
        FlowDirection.LeftToRight, 
        typeFace, 
        fontSize, 
        Brushes.Black);

    r = formattedText.Baseline;

    return r;
}

편집 : Shimmy, 귀하의 의견에 대한 응답으로, 나는 당신이 실제로이 솔루션이 작동하기 때문에 실제로 시도했다고 생각하지 않습니다. 예는 다음과 같습니다.

Example Baseline Alignment

여기 XAML이 있습니다.

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Margin" Value="0,40,0,0"/>
        </Style>
    </StackPanel.Resources>
    <StackPanel Orientation="Horizontal">
        <TextBlock Name="tb1" Text="Lorem " FontSize="10"/>
        <TextBlock Name="tbref" Text="ipsum"/>
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Name="tb2" Text="dolor "  FontSize="20"/>
        <TextBlock Text="sit"/>
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Name="tb3" Text="amet "  FontSize="30"/>
        <TextBlock Text="consectetuer"/>
    </StackPanel>
</StackPanel>

그리고 여기에 이것을 달성하는 코드가 있습니다

double baseRef = CalculateBaseline(tbref);
double base1 = CalculateBaseline(tb1) - baseRef;
double base2 = CalculateBaseline(tb2) - baseRef;
double base3 = CalculateBaseline(tb3) - baseRef;
tb1.Margin = new Thickness(0, 40 - base1, 0, 0);
tb2.Margin = new Thickness(0, 40 - base2, 0, 0);
tb3.Margin = new Thickness(0, 40 - base3, 0, 0);

다른 팁

상당히 간단한 솔루션 :

1) 레이블 대신 텍스트 블록 컨트롤을 사용하십시오. 텍스트 블록이 레이블보다 가벼운 무게이기 때문입니다. http://joshsmithonwpf.wordpress.com/2007/07/04/differences-between-label-and-textblock/

2) TextBlock 스타일에 LineHeight 및 Linestackingstrategy = BlockLineHeight를 사용하십시오. 이것은 두 가지를 기준선에서 쉽게 맞출 것입니다.

<StackPanel Orientation="Horizontal"
            VerticalAlignment="Center"
            HorizontalAlignment="Center">
    <StackPanel.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="LineHeight" Value="44pt"/>
            <Setter Property="LineStackingStrategy" Value="BlockLineHeight"/>
        </Style>
    </StackPanel.Resources>            
    <TextBlock Text="Name:"/>
    <TextBlock Text="Itzhak Perlman" FontSize="44"/>
</StackPanel>

나는 여기에 제시된 창의적인 솔루션을 정말 좋아하지만 장기적으로 (말장난 의도) 우리는 이것을 사용해야한다고 생각합니다.

<TextBlock>
   <Run FontSize="20">What</Run>
   <Run FontSize="36">ever</Run>
   <Run FontSize="12" FontWeight="Bold">FontSize</Run>
</TextBlock>

실행 요소에서 누락 된 유일한 것은 텍스트 속성의 데이터베이닝이지만 조만간 추가 될 수 있습니다.

실행은 레이블과 텍스트 상자의 정렬을 수정하지 않지만 많은 간단한 상황에서 실행은 상당히 멋지게 수행됩니다.

<TextBlock>
<InlineUIContainer BaselineAlignment="Baseline"><TextBlock>Small</TextBlock></InlineUIContainer>
<InlineUIContainer BaselineAlignment="Baseline"><TextBlock FontSize="50">Big</TextBlock></InlineUIContainer>
</TextBlock>

이것은 잘 작동합니다. 기준선/하단/센터/상단 실험.

XAML 디자이너는 정렬을 지원합니다 TextBlock 설계 시간에 기준선별 컨트롤 :

enter image description here

이것은 당신의 컨트롤에 고정 마진을 할당합니다. 글꼴 크기가 런타임에 변하지 않는 한 정렬이 보존됩니다.

실제로 간단한 답변을 찾았습니다 Aviad'에스.

요소 자체를 받아들이고 계산 된 두께를 반환하는 Aviad의 기능이 포함 된 변환기를 만들었습니다.

그런 다음 설정했습니다

<Style TargetType="TextBlock">
    <Setter Property="Margin" 
        Value="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource converters:TextAlignmentMarginConverter}}" />
</Style>

단점은 TextBlock에 템플릿이 없으므로 TemplateBinding을 통해 설정할 수 없기 때문에 원래 마진 속성을 차지한다는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top