WPF的TextBox控制元件的自動行高
阿新 • • 發佈:2021-08-30
想讓TextBox的高度自動適應內容
通過設定附加屬性attach:TextBoxAttach.AutoHeight
和TextBlock.LineHeight
<TextBox VerticalContentAlignment="Top" attach:TextBoxAttach.AutoHeight="True" AcceptsReturn="True" Text="{Binding Model.Content}" TextBlock.LineHeight="20" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" />
- 監聽AutoHeight屬性的變化,當設定為True時,如果物件是textBox,就監聽TextBox的
Loaded
,Unloaded
,TextChanged
- 當控制元件還沒Loaded的時候,是無法獲取實際行數的
- 在Unloaded事件中取消所有事件的註冊
- 控制元件高度的改變就是很簡單的事情了,獲取實際的行數和配置的行高,直接設定控制元件高度即可
有一個問題:當前是在TextChanged中,每次變更都是計算設定控制元件高度,如果可以監控到行高的變化的話,應該合理一點
public class TextBoxAttach { public static bool GetAutoHeight(DependencyObject obj) { return (bool)obj.GetValue(AutoHeightProperty); } public static void SetAutoHeight(DependencyObject obj, bool value) { obj.SetValue(AutoHeightProperty, value); } public static readonly DependencyProperty AutoHeightProperty = DependencyProperty.RegisterAttached("AutoHeight", typeof(bool), typeof(TextBoxAttach), new PropertyMetadata(false, OnChanged)); private static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is TextBox textBox)) { return; } if (textBox != null) { textBox.Loaded += TextBox_Loaded; textBox.Unloaded += TextBox_Unloaded; textBox.TextChanged += TextBox_TextChanged; } } private static void TextBox_Unloaded(object sender, RoutedEventArgs e) { var c = sender as TextBox; c.Unloaded -= TextBox_Unloaded; c.Loaded -= TextBox_Loaded; c.TextChanged -= TextBox_TextChanged; } private static void TextBox_Loaded(object sender, RoutedEventArgs e) { var c = sender as TextBox; ReSize(c); } private static void TextBox_TextChanged(object sender, TextChangedEventArgs e) { var c = sender as TextBox; if (c.IsLoaded) ReSize(c); } private static void ReSize(TextBox textBox) { var lines = textBox.LineCount; var lineHeight = (double)textBox.GetValue(TextBlock.LineHeightProperty); double height = lineHeight * lines; textBox.Height = height; } }