WPF TextBlock을 동적으로 크기를 조정할 때 성능 저하
-
12-09-2019 - |
문제
나는 현재 WPF 응용 프로그램의 레이아웃을 연구하고 있으며 내 컨트롤 중 하나의 레이아웃에 약간의 걸려있는 것 같습니다. 이 컨트롤은 동적 크기이므로 뷰포트의 크기에 맞아야합니다. 제가 실행하는 문제는 매우 시각적 인 문제이므로 설명하기 위해 최선을 다하겠습니다. 지금은 다음과 같습니다.
Alt Text http://gallery.me.com/theplatz/100006/capture/web.png?ver=12472534170001
각 "col n row x"헤더 아래의 영역은 다양한 길이의 텍스트가 배치되는 텍스트 블록입니다. TextBlock이 실제로 랩을 만들기 위해 StackoverFlow에서 텍스트 블록의 너비를 열의 너비에 바인딩하는 솔루션을 찾았습니다. 다음은 첫 번째 열에 대한 정의와 함께 그리드 정의의 스 니펫입니다.
<!-- Change Detail Contents Grid -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="270" Width="2*" />
<ColumnDefinition MinWidth="160" Width="*" />
<ColumnDefinition MinWidth="160" Width="*" />
<ColumnDefinition MinWidth="160" Width="*" />
</Grid.ColumnDefinitions>
<!--
We bind the width of the textblock to the width of this border to make sure things resize correctly.
It's important that the margin be set to 1 larger than the margin of the textblock or else you'll end
up in an infinate loop
-->
<Border Grid.Column="0" Margin="6" Name="FirstBorder" />
<Border Grid.Column="0" BorderThickness="0,0,1,0" BorderBrush="{DynamicResource ColumnBorderBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Border Style="{DynamicResource DetailHeadingBorder}">
<TextBlock Text="Col 1 Row 1" Style="{DynamicResource DetailHeadingText}" />
</Border>
<TextBlock Text="{Binding IsReason, ElementName=ChangeDetailRoot}" Style="{DynamicResource DetailText}" Width="{Binding ActualWidth, ElementName=FirstBorder}" />
</StackPanel>
<StackPanel Grid.Row="1">
<Border Style="{DynamicResource DetailHeadingBorder}">
<TextBlock Text="Col 1 Row 2" Style="{DynamicResource DetailHeadingText}" />
</Border>
<TextBlock Text="{Binding WasReason, ElementName=ChangeDetailRoot}" Style="{DynamicResource DetailText}" Width="{Binding ActualWidth, ElementName=FirstBorder}" />
</StackPanel>
</Grid>
</Border>
</Grid>
창/뷰포트 너비가 증가하면 모든 것이 잘 어울립니다. 너비가 감소하면 문제가 분명해집니다. 갑자기 최대 크기에서 원래 크기로 이동하면 모든 열이 "댄스"를 지정된 크기로 되돌립니다. 내가 의미하는 바는 각 열이 크기가 작은 크기로 비례 적으로 크기가 크기 때문에 크기가 줄어드는 것을 볼 수 있다는 것입니다. 내가 찾은 것은 이것이 직접적으로 발생한다는 것입니다.
Width="{Binding ActualWidth, ElementName=FirstBorder}"
각 텍스트 블록에. 또한 문제는 눈에 띄게 악화됩니다. 그러나 해당 라인이 없으면 각 텍스트 블록 내부의 텍스트가 오른쪽으로 계속 커지게됩니다. 열에서 마무리하는 대신 더 많은 텍스트가 추가됩니다.
내가 성취하려는 것을 달성하는 더 좋은 방법이 있습니까? HTML/CSS를 사용하면 이는 상당히 간단한 일입니다. 나는이 질문에 대한 답을 얻기 위해 STACKOVERFLOW를 통해 검색하고 살펴 보았습니다.
나는 HTML/CSS의 무거운 배경에서 왔기 때문에 이것이 WPF가 잘 어울리는 것이 아니라면 알려주십시오.
해결책
나는 내 자신의 질문에 대답하는 것을 싫어하지만, 내가 잘못하고있는 일을 발견 한 것으로 보인다. 원래 질문이 요청 된 지 너무 오래되었으므로, 내가 시도한 모든 단계를 기억할 수는 없지만 이것이 내가 아는 것입니다. 각 텍스트 블록의 스타일은 다음과 같이 설정되었습니다.
<Style x:Key="DetailText" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Margin" Value="5,5,5,5" />
</Style>
그 당시에는 원하는 결과를 생성하지 않았다고 가정하므로 텍스트 블록의 너비를 열의 너비에 바인딩해야했습니다. 오늘 놀이에서 나는 스타일을 다음과 같이 바꾸고 바인딩을 제거하고 내 문제가 해결되었다는 것을 알았습니다.
<Style x:Key="DetailText" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Margin" Value="5,5,5,5" />
</Style>
다른 팁
이것을 시도한 경우 사과하지만 TextBlock.textWrapping을 "Wrap"으로 설정하면 목표를 달성하지 않습니까?
그리드가 크기 조정을 처리 할 것이기 때문에 당신이하고있는 바인드-너비의 일에 대한 필요성을 제거 할 것이라고 생각합니다. (아마도 지금 일어나고있는 일 : 그리드는 축소 될 때 컨트롤을 배치하고 있으며 너비에 대한 바인딩은 크기를 약간 변경하여 춤을줍니다.)
업데이트
나는 당신이보고있는 행동을 복제하려고 노력했지만 그것은 나에게 잘 작동합니다. 나는 텍스트 블록에 대해 간단한 스타일을 만들었습니다.
<Style x:Key="DetailText" TargetType="{x:Type TextBlock}">
<Setter Property="TextBlock.TextWrapping" Value="Wrap"/>
</Style>
그리고 나는 당신의 다른 역동적 인 자원이 없었습니다 (DetailHeadingBorder, DetailHeadingText, or ColumnBorderBrush
), 그래서 모든 것이 흑백이었다 (미세).
어쩌면 당신은 정말 오래된 그래픽 카드를 가지고 있고 소프트웨어로 물건을 렌더링하고 있습니까? 또는 그것은 당신과 관련이 있습니다 styles
.
나는 당신의 질문을 잘못 해석하지 않았기를 바랍니다. 그러나 텍스트 블록을 바인딩 할 필요가 없습니까?
이 xaml은 올바르게 작동하는 것 같습니다.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="270"
Width="2*" />
<ColumnDefinition MinWidth="160"
Width="*" />
<ColumnDefinition MinWidth="160"
Width="*" />
<ColumnDefinition MinWidth="160"
Width="*" />
</Grid.ColumnDefinitions>
<!-- We bind the width of the textblock to the width of this border to make sure things resize correctly.
It's important that the margin be set to 1 larger than the margin of the textblock or else you'll end
up in an infinate loop -->
<Border Grid.Column="0"
BorderThickness="0,0,1,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Border>
<TextBlock Text="Col 1 Row 1" />
</Border>
<TextBlock TextWrapping="Wrap"
Text="gfege dfh lh dfl dhliöslghklj h lglsdg fklghglfg flg lgheh" />
</StackPanel>
<StackPanel Grid.Row="1">
<Border>
<TextBlock Text="Col 1 Row 2" />
</Border>
<TextBlock Text="Massor av text som blir en wrappning i slutändan hoppas jag"
TextWrapping="Wrap" />
</StackPanel>
</Grid>
</Border>
</Grid>
방금 너비 바인딩을 제거하고 텍스트 트래핑 (아마도 스타일로 가졌던)을 추가하고 "FirstBorder"라는 테두리도 제거했습니다.