TextWrapping을 "줄 바꾸기"로 설정하면 WPF TextBlock에 여러 줄의 텍스트를 포함 할 수 있습니다. 텍스트 줄 수를 얻는 데 "깨끗한"방법이 있습니까? 원하는 높이를보고 각 높이의 예상 높이로 나누는 것을 고려했습니다. 그러나, 그것은 상당히 더러운 것처럼 보입니다. 더 좋은 방법이 있습니까?TextBlock의 표시 줄 수
답변
WPF에 대한 한 가지 중요한 점은 모든 컨트롤이 매우 눈에 띄지 않는다는 것입니다. 이 때문에 우리는 TextBox을 사용할 수 있습니다.이 속성에는 LineCount 속성이 있습니다 (왜 이것이 DependencyProperty가 아니며, 왜 TextBlock에는 모름). TextBox를 사용하면 간단하게 다시 템플릿을 만들 수 있으므로 TextBlock과 유사하게 동작합니다. 사용자 정의 스타일/템플릿에서는 IsEnabled를 False로 설정하고 컨트롤의 기본 템플릿을 다시 만들어 비활성화 된 모양이 더 이상 나타나지 않도록합니다. 또한 TemplateBindings를 사용하여 Background와 같이 유지하려는 모든 속성을 바인딩 할 수 있습니다.
이제<Style x:Key="Local_TextBox"
TargetType="{x:Type TextBoxBase}">
<Setter Property="IsEnabled"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border Name="Border"
Background="{TemplateBinding Background}">
<ScrollViewer x:Name="PART_ContentHost" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
, 그것은 우리의 텍스트 상자 모양을 돌봐하고있는 TextBlock처럼 행동하지만, 우리는 어떻게 선을 계산합니까 것인가?
글쎄, 우리가 코드 뒤에 직접 접근하고 싶다면 TextBox의 SizeChanged 이벤트에 등록 할 수 있습니다. 그러나
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LongText = "This is a long line that has lots of text in it. Because it is a long line, if a TextBlock's TextWrapping property is set to wrap then the text will wrap onto new lines. However, we can also use wrapping on a TextBox, that has some diffrent properties availible and then re-template it to look just like a TextBlock!";
uiTextBox.SizeChanged += new SizeChangedEventHandler(uiTextBox_SizeChanged);
this.DataContext = this;
}
void uiTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
{
Lines = uiTextBox.LineCount;
}
public string LongText { get; set; }
public int Lines
{
get { return (int)GetValue(LinesProperty); }
set { SetValue(LinesProperty, value); }
}
// Using a DependencyProperty as the backing store for Lines. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LinesProperty =
DependencyProperty.Register("Lines", typeof(int), typeof(MainWindow), new UIPropertyMetadata(-1));
}
, 그때 다른 장소 현재 창에 같은 속성을 사용해야하는 경향이, 및/또는 MVVM을 사용하고 그 방법을 먹고 싶어하지 않기 때문에, 우리는 몇 가지 AttachedProperties를 만들 수 있습니다 LineCount의 검색 및 설정을 처리합니다. AttachedProperties를 사용하여 동일한 작업을 수행 할 것입니다. 이제는 임의의 TextBox와 함께 사용할 수 있으며 Window의 DataContext 대신 TextBox를 통해 바인딩 할 수 있습니다.
public class AttachedProperties
{
#region BindableLineCount AttachedProperty
public static int GetBindableLineCount(DependencyObject obj)
{
return (int)obj.GetValue(BindableLineCountProperty);
}
public static void SetBindableLineCount(DependencyObject obj, int value)
{
obj.SetValue(BindableLineCountProperty, value);
}
// Using a DependencyProperty as the backing store for BindableLineCount. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BindableLineCountProperty =
DependencyProperty.RegisterAttached(
"BindableLineCount",
typeof(int),
typeof(MainWindow),
new UIPropertyMetadata(-1));
#endregion // BindableLineCount AttachedProperty
#region HasBindableLineCount AttachedProperty
public static bool GetHasBindableLineCount(DependencyObject obj)
{
return (bool)obj.GetValue(HasBindableLineCountProperty);
}
public static void SetHasBindableLineCount(DependencyObject obj, bool value)
{
obj.SetValue(HasBindableLineCountProperty, value);
}
// Using a DependencyProperty as the backing store for HasBindableLineCount. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HasBindableLineCountProperty =
DependencyProperty.RegisterAttached(
"HasBindableLineCount",
typeof(bool),
typeof(MainWindow),
new UIPropertyMetadata(
false,
new PropertyChangedCallback(OnHasBindableLineCountChanged)));
private static void OnHasBindableLineCountChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var textBox = (TextBox)o;
if ((e.NewValue as bool?) == true)
{
textBox.SetValue(BindableLineCountProperty, textBox.LineCount);
textBox.SizeChanged += new SizeChangedEventHandler(box_SizeChanged);
}
else
{
textBox.SizeChanged -= new SizeChangedEventHandler(box_SizeChanged);
}
}
static void box_SizeChanged(object sender, SizeChangedEventArgs e)
{
var textBox = (TextBox)sender;
(textBox).SetValue(BindableLineCountProperty, (textBox).LineCount);
}
#endregion // HasBindableLineCount AttachedProperty
}
지금, 그것은 LineCount을 찾기 위해 간단합니다
<StackPanel>
<TextBox x:Name="uiTextBox"
TextWrapping="Wrap"
local:AttachedProperties.HasBindableLineCount="True"
Text="{Binding LongText}"
Style="{StaticResource Local_TextBox}" />
<TextBlock Text="{Binding Lines, StringFormat=Binding through the code behind: {0}}" />
<TextBlock Text="{Binding ElementName=uiTextBox, Path=(local:AttachedProperties.BindableLineCount), StringFormat=Binding through AttachedProperties: {0}}" />
</StackPanel>
간단한 방법은 LineCount 속성입니다. 또한 GetLastVisibleLineIndex라는 메서드를 사용하면 텍스트 상자에서 스크롤 막대없이 표시 할 수있는 선의 수를 알 수 있습니다.
줄을 추가하는시기를 알고 싶으면 TextChanged 이벤트에서 듣고 LineCount 속성에 대해 물어보십시오 (비교를 수행하려면 las LineCount를 변수로 유지해야합니다).
TextBlock에 LineCount 속성이 없습니다. 그것은 전적으로 TextBox의 도메인입니다. –
그게 유용하다고. 좋은 정보, 틀린 대답. – mdw7326
// this seems to do the job
<TextBox x:Name="DescriptionTextBox"
Grid.Row="03"
Grid.RowSpan="3"
Grid.Column="01"
Width="100"
AcceptsReturn="True"
MaxLength="100"
MaxLines="3"
PreviewKeyDown="DescriptionTextBox_PreviewKeyDown"
Text="{Binding Path=Description,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
/// <summary>
/// we need to limit a multi line textbox at entry time
/// </summary>
/// <param name="sender">
/// The sender.
/// </param>
/// <param name="e">
/// The e.
/// </param>
private void DescriptionTextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
TextBox thisTextBox = sender as TextBox;
if (thisTextBox != null)
{
// only check if we have passed the MaxLines
if (thisTextBox.LineCount > thisTextBox.MaxLines)
{
// we are going to discard the last entered character
int numChars = thisTextBox.Text.Length;
// force the issue
thisTextBox.Text = thisTextBox.Text.Substring(0, numChars - 1);
// set the cursor back to the last allowable character
thisTextBox.SelectionStart = numChars - 1;
// disallow the key being passed in
e.Handled = true;
}
}
}
질문은 TextBox가 아니라 TextBlock에 관한 것입니다. – jHilscher
나는이 질문은 이미 7 세 것을 봐 왔지만, 난 그냥 솔루션과 함께 제공 :
TextBlock입니다이 LineCount라는 개인 속성이 있습니다. 이 값을 읽는 확장 메서드를 만들었습니다.
public static class TextBlockExtension
{
public static int GetLineCount(this TextBlock tb)
{
var propertyInfo = GetPrivatePropertyInfo(typeof(TextBlock), "LineCount");
var result = (int)propertyInfo.GetValue(tb);
return result;
}
private static PropertyInfo GetPrivatePropertyInfo(Type type, string propertyName)
{
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic);
return props.FirstOrDefault(propInfo => propInfo.Name == propertyName);
}
}
- 1. 프로그램의 작업 표시 줄 아이콘에 진행률 표시 줄 표시
- 2. Compact Framework에서 여러 줄 텍스트 상자의 표시 줄 수 얻기
- 3. 구성 요소에서 생성 된 PDF가 WPF TextBlock의 줄 바꿈과 정확히 일치 할 수 있습니까?
- 4. LWUIT 진행률 표시 줄
- 5. wxPython 진행률 표시 줄
- 6. Java로드/진행 표시 줄
- 7. VBA 상태 표시 줄
- 8. 글로벌 상태 표시 줄
- 9. 탭 표시 줄 항목이
- 10. Android의 하단 표시 줄
- 11. Paperclip 진행률 표시 줄
- 12. 상태 표시 줄 이외의 활동에 알림을 표시 할 수 있습니까?
- 13. 셀레늄 주소 표시 줄
- 14. 제목 표시 줄 아래
- 15. 진행률 표시 줄
- 16. 탭 표시 줄 항목
- 17. 진행 표시 줄 문제
- 18. 다중 진행 표시 줄
- 19. 유연한 진행 표시 줄
- 20. Android의 진행 표시 줄
- 21. android 진행률 표시 줄
- 22. 진행률 표시 줄 - HTTP 요청에 대한 진행률 표시 줄 - Blackberry
- 23. WinForms의 진행 표시 줄
- 24. 업로드 진행률 표시 줄
- 25. 알림/작업 표시 줄
- 26. jquery 진행률 표시 줄
- 27. AudioClip 진행률 표시 줄
- 28. 진행 표시 줄 도움말
- 29. UITableView 검색 표시 줄?
- 30. Android ..... 진행률 표시 줄
이것은 훌륭합니다. 그러나 TextBox는 글꼴 모음/글꼴 크기가 동일하므로 TextBlock보다 제한적입니다. 결과적으로 라인 수를 계산하기가 쉽습니다. 반면 TextBlocks는 높이가 다른 인라인을 가질 수 있습니다. 이것은 일을 다소 어렵게 만듭니다. – tom7