TextWrappingを "Wrap"に設定すると、WPF TextBlockに複数行のテキストを含めることができます。 テキスト行数を取得する「クリーン」な方法はありますか?私は、希望の高さを見て、それを各行の推定高さで割ることを検討しました。しかし、それはかなり汚れているようです。より良い方法がありますか?TextBlockの表示行数
答えて
WPFについてのすばらしい点の1つは、すべてのコントロールが非常に見苦しいことです。このため、TextBoxを使用することができます。これはLineCountプロパティを持っています(なぜそれがDependencyPropertyでないのか、またはTextBlockにはわからないのはなぜですか)。 TextBoxを使うと、それを再テンプレートして、それが動作し、TextBlockのように見えるようにすることができます。私たちのカスタムスタイル/テンプレートでは、IsEnabledをFalseに設定し、コントロールの基本的な再テンプレートを作成して、無効な外観がなくなるようにします。 TemplateBindingsを使用して、バックグラウンドのように維持したいプロパティをバインドすることもできます。
<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>
さて、それは私たちのTextBoxの外観を作るの世話をし、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
}
さて、それはラインカウントを見つけることは簡単です:
<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>
簡単な方法は、ラインカウントプロパティです。また、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;
}
}
}
質問はテキストボックスではなくTextBlockに関するものでした。 – jHilscher
私はこの質問はすでに7歳であることを見てきましたが、私はちょうどソリューションに付属している:
のTextBlockがラインカウントと呼ばれる私有財産を持っています。この値を読み取る拡張メソッドを作成しました:
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. TextBlock Textのツールヒント(カスタムスタイル付き)を表示
- 2. wpf TextBlockコントロールでエラーメッセージを表示
- 3. TextBlock(WPF)で画像を表示
- 4. WPFでHTMLを表示するTextBlock
- 5. フルスクリーン表示時にMediaElementにTextBlockを表示
- 6. WPF複数行のTextBlock CenterAlignment問題
- 7. 表示行数
- 8. UWPはTextBlockにテキストの折り返し表示を表示します
- 9. 行数と次の行の表示数
- 10. TextBlockとProgressBarの進捗状況を表示するには?
- 11. TextBlockの複数の色
- 12. TextBlockの文字数制限
- 13. WindowsPhone 8.0でスマイリーシンボルを表示するTextBlockコントロール
- 14. WP7 TextBlockにデータを表示するには?
- 15. TextBlock WPFでバインドして表示するリンク
- 16. TextBlockテキストを文字単位で表示させる
- 17. Jquery複数の表の行を表示/非表示
- 18. igDataChartで複数のシリーズの行を表示/非表示
- 19. 複数のデータ行を表示し、jsonデータを表示する
- 20. 関数値への行の表示
- 21. WPF ComboBoxのようにDataGridのTextBlockにリレーショナルデータを表示する方法
- 22. リストビューで最大24の行数と100の行数を表示
- 23. windows phone appを作成するときにtextblock要素に1行のテキストしか表示されない
- 24. Ag-gridの行数を表示
- 25. Drupalビューの行数を表示
- 26. 複数の行に1列を表示
- 27. TextBlockバインディングは空の文字列ではなくクラス名を表示します
- 28. WPF検証エラー:ツールチップではなく別のTextBlockで表示する方法
- 29. ComboBoxのTextBlockにバインドされた文字列が表示されない
- 30. GridViewColumn.CellTemplateのStackPanelでTextBlockをマルチバインドしてもテキストが表示されない
これは素晴らしいです。 しかし、TextBoxは、一様なフォントファミリ/フォントサイズを持つため、TextBlockよりも制限があります。その結果、行数を計算するのは簡単です。一方、TextBlocksは異なる高さで異なるインラインを持つことができます。これは物事をやや難しくしています。 – tom7