如何在wpf中设置内部TextBoxView上的边距
我有一个案例,我想最小化文本框的水平填充。
使用snoop我发现文本框由多个子控件组成。 其中一个是TextBoxView,边距为2,0,2,0
TextBoxView是一个内部wpf组件,没有公共API。
你会如何摆脱“内部填充”?
将外边距设置为-2,0,-2,0以补偿填充。
我创建了一个自定义控件来删除内部填充。
public class MyTextBox : TextBox { public MyTextBox() { Loaded += OnLoaded; } void OnLoaded(object sender, RoutedEventArgs e) { // the internal TextBoxView has a margin of 2,0,2,0 that needs to be removed var contentHost = Template.FindName("PART_ContentHost", this) as ScrollViewer; if (contentHost != null && contentHost.Content != null && contentHost.Content is FrameworkElement) { var textBoxView = contentHost.Content as FrameworkElement; textBoxView.Margin = new Thickness(0,0,0,0); } } }
这是一种肮脏的方式:
public static class TextBoxView { public static readonly DependencyProperty MarginProperty = DependencyProperty.RegisterAttached( "Margin", typeof(Thickness?), typeof(TextBoxView), new PropertyMetadata(null, OnTextBoxViewMarginChanged)); public static void SetMargin(TextBox element, Thickness? value) { element.SetValue(MarginProperty, value); } [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)] [AttachedPropertyBrowsableForType(typeof(TextBox))] public static Thickness? GetMargin(TextBox element) { return (Thickness?)element.GetValue(MarginProperty); } private static void OnTextBoxViewMarginChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var textBox = (TextBox)d; OnTextBoxViewMarginChanged(textBox, (Thickness?)e.NewValue); } private static void OnTextBoxViewMarginChanged(TextBox textBox, Thickness? margin) { if (!textBox.IsLoaded) { textBox.Dispatcher.BeginInvoke( DispatcherPriority.Loaded, new Action(() => OnTextBoxViewMarginChanged(textBox, margin))); return; } var textBoxView = textBox.NestedChildren() .SingleOrDefault(x => x.GetType().Name == "TextBoxView"); if (margin == null) { textBoxView?.ClearValue(FrameworkElement.MarginProperty); } else { textBoxView?.SetValue(FrameworkElement.MarginProperty, margin); } } private static IEnumerable NestedChildren(this DependencyObject parent) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); yield return child; if (VisualTreeHelper.GetChildrenCount(child) == 0) { continue; } foreach (var nestedChild in NestedChildren(child)) { yield return nestedChild; } } } }
它允许在文本框上设置边距:
根本没有针对性能进行优化。