C# 如何在wpf中设置内部TextBoxView的边距

C# 如何在wpf中设置内部TextBoxView的边距,c#,wpf,textbox,margin,padding,C#,Wpf,Textbox,Margin,Padding,我有一个例子,我想最小化文本框的水平填充 使用snoop,我发现文本框由多个子控件组成。 其中之一是边距为2,0,2,0的TextBoxView TextBoxView是一个内部wpf组件,没有公共API 如何去除“内部填充”?将外部边距设置为-2,0,-2,0以补偿填充。我创建了一个自定义控件来删除该内部填充 public class MyTextBox : TextBox { public MyTextBox() { Loaded += OnLoaded;

我有一个例子,我想最小化文本框的水平填充

使用snoop,我发现文本框由多个子控件组成。 其中之一是边距为2,0,2,0的TextBoxView

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<DependencyObject> 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;
            }
        }
    }
}
公共静态类TextBoxView
{
公共静态只读DependencyProperty MarginProperty=DependencyProperty.RegisterAttached(
“保证金”,
类型(厚度?),
类型(TextBoxView),
新的PropertyMetadata(null,OnTextBoxViewMarginChanged));
公共静态空白设置边距(文本框元素,厚度?值)
{
元素设置值(MarginProperty,value);
}
[AttachedPropertyBrowsableForChildren(包括Descendants=false)]
[AttachedPropertyBrowsableForType(typeof(TextBox))]
公共静态厚度?GetMargin(文本框元素)
{
返回(厚度?)元素.GetValue(MarginProperty);
}
私有静态void OnTextBoxViewMarginChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
var textBox=(textBox)d;
OnTextBoxViewMarginChanged(文本框,(厚度?)e.NewValue);
}
私有静态无效OnTextBoxViewMarginChanged(文本框文本框,厚度?边距)
{
如果(!textBox.IsLoaded)
{
textBox.Dispatcher.BeginInvoke(
DispatcherPriority.已加载,
新操作(()=>OnTextBoxViewMarginChanged(文本框,边距));
返回;
}
var textBoxView=textBox.NestedChildren()
.SingleOrDefault(x=>x.GetType().Name==“TextBoxView”);
如果(边距==null)
{
textBoxView?.ClearValue(FrameworkElement.MarginProperty);
}
其他的
{
textBoxView?.SetValue(FrameworkElement.MarginProperty,边距);
}
}
私有静态IEnumerable嵌套子对象(此DependencyObject父对象)
{
for(int i=0;i
它允许设置文本框的边距:

<Style TargetType="{x:Type TextBox}">
    <Setter Property="demo:TextBoxView.Margin" Value="1,0" />
</Style>


根本没有针对性能进行优化。

TextBoxView在问题中应用了边距(而不是填充)错误的文本,我将更新此内容。将父控件的边距设置为-2似乎没有帮助。好主意。对我来说是可行的,但是我还是禁用了边框,并且还需要将背景设置为
{x:Null}
,这在我的情况下是可以的。