theqs1000
theqs1000

Reputation: 377

Putting icon in a textbox in XAML (WPF)

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

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

<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

Upvotes: 3

Views: 17595

Answers (3)

Andy
Andy

Reputation: 6466

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.

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}.

        <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>

Upvotes: 0

RoelF
RoelF

Reputation: 7573

Instead of overwriting the template, I would create a new simple 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}"/>

Upvotes: 3

Blachshma
Blachshma

Reputation: 17385

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.

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't have to overwrite all the properties of the textbox, just the Template property. This can easily be done using the BasedOn attribute:

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

Upvotes: 0

Related Questions