自定义文本框 - WPF 和 Xaml

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19029299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:44:11  来源:igfitidea点击:

A custom Textbox - WPF and Xaml

c#wpfxaml

提问by Kasrak

I want to make a custom TextBoxusing XAML and a custom class with an additional property to TextBox called PosType. PosTypewill be rendered inside the red triangle in the side.

我想TextBox使用 XAML 和一个自定义类进行自定义,该类具有名为PosType. PosType将呈现在侧面的红色三角形内。

The TextBoxshould be an ordinary textbox with enough margin from left to not intercept the other text. Here is the Image showing the desired look of the textbox.

TextBox应该是有足够的余量普通文本框从左不拦截其他文本。这是显示文本框所需外观的图像。

The desired text box

所需的文本框

The Control class :

控制类:

public class PosTextBox : TextBox
{
    public string PosType { get; set; }
}

**The style I wrote : (quite similar approach to what I want except here I used border and other parts may not be accurate. **

**我写的风格:(与我想要的方法非常相似,除了这里我使用了边框和其他部分可能不准确。**

xmlns:Pro="clr-namespace:Prox.XamlControls">

<!-- Custom TextBox  -->
<Style x:Key="c1PosTextBox" TargetType="{x:Type Pro:PosTextBox}" >
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Pro:PosTextBox}">

                <Grid>
                    <Border>
                        <Border>
                            <TextBlock Text ="{TemplateBinding Path= Pro:PosType}"></TextBlock>
                            <!--<TextBlock Text ="{TemplateBinding ElementName=Pro:PosTextBox, Path= Pro:PosType}"></TextBlock>-->
                        </Border>
                    </Border>
                    <Border Margin="5,10,5,10">
                        <ContentPresenter  Name="Content" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" TextBlock.Foreground="White"></ContentPresenter>
                    </Border>
                </Grid>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

How to create this custom textbox and achieve the desired look?

如何创建此自定义文本框并获得所需的外观?

Edit:Please guide me to fix the minor issues based on the same approach I mentioned above.

编辑:请指导我根据我上面提到的相同方法解决小问题。

回答by Omri Btian

You could do that using Adorners

你可以使用Adorners做到这一点

Adorners are rendered in a different layer called AdornerLayeron top of the UIElement, Which can get you the desired affect.

装饰器呈现在AdornerLayer之上的不同层中UIElement,这可以为您提供所需的效果。

public class PosTypeAdorner : Adorner
{
     private string _posText;

     // Be sure to call the base class constructor. 
     public PosTypeAdorner (UIElement adornedElement, string posText) : base(adornedElement) 
     { 
           _posText = posText;
     }

     // A common way to implement an adorner's rendering behavior is to override the OnRender 
     // method, which is called by the layout system as part of a rendering pass. 
     protected override void OnRender(DrawingContext drawingContext)
     {
          // Draw the red triangle with it's text using the drawingContext here
     }
 }

Assuming you want the text of the PosTypeto be bindable, you should make it as a Dependency property. Use OnApplyTemplateto attach the adorner to your text box

假设您希望 的文本PosType可绑定,您应该将其设置为Dependency property. 使用OnApplyTemplate的装饰器连接到您的文本框中

public class PosTextBox : TextBox
{
    public PosTextBox()
    {
    }

    public static readonly DependencyProperty PosTypeProperty =
        DependencyProperty.Register("PosType", typeof (string), typeof (PosTextBox), new PropertyMetadata(default(string)));

    public string PosType
    {
        get { return (string)GetValue(PosTypeProperty); }
        set { SetValue(PosTypeProperty, value); }
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        var layer = AdornerLayer.GetAdornerLayer(this);
        var posAdorner = new PosTypeAdorner(this, PosType);

        layer.Add(posAdorner);
    }
}

For more information, you can check out this links:

有关更多信息,您可以查看此链接:

http://www.codeproject.com/Articles/54472/Defining-WPF-Adorners-in-XAML

http://www.codeproject.com/Articles/54472/Defining-WPF-Adorners-in-XAML

http://www.nbdtech.com/Blog/archive/2010/06/21/wpf-adorners-part-1-ndash-what-are-adorners.aspx

http://www.nbdtech.com/Blog/archive/2010/06/21/wpf-adorners-part-1-ndash-what-are-adorners.aspx

http://www.nbdtech.com/Blog/archive/2010/06/28/wpf-adorners-part-2-ndash-placing-any-control-on-the.aspx

http://www.nbdtech.com/Blog/archive/2010/06/28/wpf-adorners-part-2-ndash-placing-any-control-on-the.aspx

Good luck

祝你好运