将图标放在 XAML (WPF) 的文本框中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14319981/
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 07:01:23  来源:igfitidea点击:

Putting icon in a textbox in XAML (WPF)

wpftextboxicons

提问by theqs1000

I want to put a small icon (a png file) in to the corner of a textbox. A sketch of what I mean is at http://dosketch.com/view.php?k=mIPeHLSBLx0e2YpoVpYO

我想将一个小图标(一个 png 文件)放在文本框的一角。我的意思的草图是在http://dosketch.com/view.php?k=mIPeHLSBLx0e2YpoVpYO

So far I've got (in my main xaml file)

到目前为止,我有(在我的主 xaml 文件中)

<TextBox Style="{StaticResource IconTextBox"} ...

and in my resources area:

在我的资源区:

<Style x:Key="IconTextBox" TargetType="TextBox">
 <Setter Property="Template">
  <Setter.Value>
   <ControlTemplate TargetType="TextBox">
     <Image Source="icon.png" />
   </ControlTemplate>
  </Setter.Value>
 </Setter>
</Style>

Obviously this isn't working (I'm losing the textbox for a start!). Ideally when the user is typing into the textbox, the text doesn't overlap the image - but for the time being I'll just be happy getting the image in the textbox.

显然这是行不通的(我一开始就丢失了文本框!)。理想情况下,当用户在文本框中键入内容时,文本不会与图像重叠 - 但目前我会很高兴在文本框中获取图像。

Thanks

谢谢

回答by RoelF

Instead of overwriting the template, I would create a new simple UserControl:

我将创建一个新的简单 UserControl,而不是覆盖模板:

//pseudocode, does not compile!
<UserControl x:Class="MyUserControl" x:Name="root">
    <Grid>
        <!-- put some effort in aligning the items so it looks nice -->
        <TextBox Text="{Binding ElementName=root, Path=Text}" />
        <Image Source="{Binding ElementName=root, Path=IconSource}" />
    </Grid>
</UserControl>

public class MyUserControl : UserControl{
    dependencyproperty string Text;
    dependencyproperty string IconSource;
}

so you can use it as follows:

所以你可以按如下方式使用它:

<my:MyUserControl Text="{Binding MyText}" IconSource="{Binding MyIcon}"/>

回答by Blachshma

Unfortunately, whenever you want to change a template of a control in WPF, you're going to have to overwrite the entire template, you can't just modify a small part of it.

不幸的是,每当您想更改 WPF 中控件的模板时,您将不得不覆盖整个模板,您不能只修改其中的一小部分。

Luckily, all the templates are openly available. For instance, this is the textbox's default template.

幸运的是,所有模板都是公开可用的。例如,这是文本框的默认模板

So in order to add an image to a textbox, take the entire textbox template from the link above, and just add the image wherever you see fit...

因此,要将图像添加到文本框,请从上面的链接中获取整个文本框模板,然后将图像添加到您认为合适的任何位置...

As pointed out in the comments, you don'thave to overwrite all the properties of the textbox, just the Templateproperty. This can easily be done using the BasedOnattribute:

正如评论中所指出的,您不必覆盖文本框的所有属性,只需覆盖Template属性即可。这可以使用BasedOn属性轻松完成:

<Style x:Key="IconTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
   <Setter Property="Template">
       ....
   </Setter>
</Style>

回答by Andy

You could actually just add a textbox in to the textbox style that you want to create, this wouldn't actually give you an image you can change the source of though since it would be hard coded in to the xaml, I guess you could create an attached property to pass that info on.

您实际上可以在要创建的文本框样式中添加一个文本框,这实际上不会为您提供可以更改源的图像,因为它会被硬编码到 xaml 中,我想您可以创建传递该信息的附加属性。

anyway, the important part of this is that if you want to use a textbox inside the style for a textbox you have to set the inner textbox style to {x:null}.

无论如何,其中的重要部分是,如果您想在文本框的样式内使用文本框,则必须将内部文本框样式设置为 {x:null}。

        <Style TargetType="TextBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="50"/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Style="{x:Null}" Grid.Column="0" 
                                       Text="{TemplateBinding Text}"
                                       Foreground="{TemplateBinding Foreground}"                                           
                                       Background="{TemplateBinding Background}" 
                                       FontFamily="{TemplateBinding FontFamily}"
                                       FontSize="{TemplateBinding FontSize}"
                                       FontWeight="{TemplateBinding FontWeight}"/>

                            <Image Grid.Column="1" Source=">Insert your image source here."/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>