0

I want to create a SearchTextBox (deriving from original TextBox) that contains a label with the count of results. The .xaml file should also derive from the original TextBox, like:

<TextBox>
    <TextBox.Style>
        <Style>
            ...
        </Style>
    </TextBox.Style>
</TextBox>

and shouldn't be just a style in the resource directory.

Here is the original TextBox and how it should look like:

Original TextBox New TextBox

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
Finn
  • 59
  • 5

1 Answers1

1

You can create a custom control:

CustomTextBox.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace TextBoxExample;

public class CustomTextBox : TextBox
{
    public string FooterText
    {
        get => (string)GetValue(FooterTextProperty);
        set => SetValue(FooterTextProperty, value);
    }

    public static readonly DependencyProperty FooterTextProperty =
        DependencyProperty.Register(
            nameof(FooterText),
            typeof(string),
            typeof(CustomTextBox),
            new PropertyMetadata(string.Empty));
}

And use it like this:

<StackPanel>
    <NumberBox
        x:Name="CountNumberBox"
        Value="5" />
    <local:CustomTextBox
        FooterText="{x:Bind CountNumberBox.Value, Mode=OneWay}"
        PlaceholderText="Search...">
        <TextBox.Style>
            <Style
                BasedOn="{StaticResource DefaultTextBoxStyle}"
                TargetType="local:CustomTextBox">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="local:CustomTextBox">
                            <Grid>
                                :
                                :
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="*" />
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <ContentPresenter
                                    x:Name="HeaderContentPresenter"
                                    Grid.Row="0"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="2"
                                    Margin="{ThemeResource TextBoxTopHeaderMargin}"
                                    VerticalAlignment="Top"
                                    x:DeferLoadStrategy="Lazy"
                                    Content="{TemplateBinding Header}"
                                    ContentTemplate="{TemplateBinding HeaderTemplate}"
                                    FontWeight="Normal"
                                    Foreground="{ThemeResource TextControlHeaderForeground}"
                                    TextWrapping="Wrap"
                                    Visibility="Collapsed" />
                                <Border
                                    x:Name="BorderElement"
                                    Grid.Row="1"
                                    Grid.RowSpan="1"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="2"
                                    MinWidth="{TemplateBinding MinWidth}"
                                    MinHeight="{TemplateBinding MinHeight}"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    Control.IsTemplateFocusTarget="True"
                                    CornerRadius="{TemplateBinding CornerRadius}" />
                                <ScrollViewer
                                    x:Name="ContentElement"
                                    Grid.Row="1"
                                    Grid.Column="0"
                                    Margin="{TemplateBinding BorderThickness}"
                                    Padding="{TemplateBinding Padding}"
                                    AutomationProperties.AccessibilityView="Raw"
                                    Foreground="{TemplateBinding Foreground}"
                                    HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                    HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                    IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                    IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                    IsTabStop="False"
                                    IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                    VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                    VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                    ZoomMode="Disabled" />
                                <TextBlock
                                    x:Name="PlaceholderTextContentPresenter"
                                    Grid.Row="1"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="3"
                                    Margin="{TemplateBinding BorderThickness}"
                                    Padding="{TemplateBinding Padding}"
                                    Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}"
                                    IsHitTestVisible="False"
                                    Text="{TemplateBinding PlaceholderText}"
                                    TextAlignment="{TemplateBinding TextAlignment}"
                                    TextWrapping="{TemplateBinding TextWrapping}" />

                                <!--  FooterTextPresenter  -->
                                <TextBlock
                                    x:Name="FooterTextPresenter"
                                    Grid.Row="1"
                                    Grid.Column="1"
                                    Margin="{TemplateBinding BorderThickness}"
                                    Padding="{TemplateBinding Padding}"
                                    VerticalAlignment="Center"
                                    Text="{TemplateBinding FooterText}" />

                                <Button
                                    x:Name="DeleteButton"
                                    Grid.Row="1"
                                    Grid.Column="2"
                                    Width="30"
                                    Padding="{ThemeResource HelperButtonThemePadding}"
                                    VerticalAlignment="Stretch"
                                    AutomationProperties.AccessibilityView="Raw"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="{TemplateBinding CornerRadius}"
                                    FontSize="{TemplateBinding FontSize}"
                                    IsTabStop="False"
                                    Style="{StaticResource DeleteButtonStyle}"
                                    Visibility="Collapsed" />
                                    <ContentPresenter
                                    x:Name="DescriptionPresenter"
                                    Grid.Row="2"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="3"
                                    x:Load="False"
                                    AutomationProperties.AccessibilityView="Raw"
                                    Content="{TemplateBinding Description}"
                                    Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}" />
                                :
                                :
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TextBox.Style>
    </local:CustomTextBox>
</StackPanel>

Note that I omitted a bunch of code from the style for this answer. Basically, you just need to bring the DefaultTextBoxStyle from generic.xaml, add a column for the footer, add the footer and adjust a few column indexes.

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21