The text box bottom border on UWP application is not visible - c#

I am a creating a UWP application for the first time and I am encountering a weird problem where textbox's bottom border disappears if the textbox height is less than 32 (Default textbox size).
I want the textbox to be of height 25 and not 32. So, what should I do to get the bottom border of the textbox to remain and the size of textbox be 25?

In short, you need to make a custom style for your TextBox.
The steps: Go to 'Document Outline -> Right click your TextBox -> Edit Template -> Edit a Copy.'
Then, find the <Border x:Name="BorderElement"> element in this style and set its MinHeight that you want.
<Page.Resources>
<Style x:Key="TextBoxStyle1" TargetType="TextBox">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
...
<ContentPresenter x:Name="HeaderContentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.ColumnSpan="2" Grid.Column="0" FontWeight="Normal" Foreground="{ThemeResource TextControlHeaderForeground}" Margin="{StaticResource TextBoxTopHeaderMargin}" Grid.Row="0" TextWrapping="Wrap" VerticalAlignment="Top" Visibility="Collapsed" x:DeferLoadStrategy="Lazy" />
<Border x:Name="BorderElement" MinHeight="25" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}" Grid.ColumnSpan="2" Grid.Column="0" Control.IsTemplateFocusTarget="True" MinWidth="{ThemeResource TextControlThemeMinWidth}" Grid.RowSpan="1" Grid.Row="1" />
<ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" Grid.Column="0" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsTabStop="False" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ZoomMode="Disabled" />
<TextBlock x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Grid.Column="0" Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource Mode=TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" Text="{TemplateBinding PlaceholderText}" TextWrapping="{TemplateBinding TextWrapping}" TextAlignment="{TemplateBinding TextAlignment}" />
<Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Margin="{ThemeResource HelperButtonThemePadding}" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" VerticalAlignment="Stretch" Visibility="Collapsed" />
<ContentPresenter x:Name="DescriptionPresenter" AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Description}" Grid.ColumnSpan="2" Grid.Column="0" Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}" Grid.Row="2" x:Load="False" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid>
<TextBox Style="{StaticResource TextBoxStyle1}" Height="25"></TextBox>
</Grid>
Please note that I only change the MinHeight for it, if you input in it, you will find that Its text display is incomplete. If you want to make it look better. You need to do more customization.
Please read Tutorial: Create custom styles and Control templates for more information.

This is a regression in Windows 10, version 1806 (build 17763). Previous version - Fall creators update (build 16299) doesn't have this issue.
Removing MinWidth="{ThemeResource TextControlThemeMinWidth}" on a Border element in TextBox style definition as suggested above fixes it.

Related

How to place on spinbutton on top of another in NumericUpDown? | Avalonia UI

Default NumericUpDown looks like that:
,
and because of buttons take a lot of place I want to make it more Windows form style, like this:
.
I've tried to play with ButtonSpinner Styles, but didn't work out, it shrinks the whole NumericUpDown, not only ButtonSpinner (even if I write another style for NumericUpDown).
<Style Selector="ButtonSpinner">
<Setter Property="Height">
<Setter.Value>
10
</Setter.Value>
</Setter>
<Setter Property="Width">
<Setter.Value>
25
</Setter.Value>
</Setter>
</Style>
What I should do to achieve desired result?
There are two solutions:
You could modify the ButtonSpinner template (or NumericUpDown /template/ ButtonSpinner template) to use the UniformGrid with 2 rows instead of StackPanel with horizontal orientation used by the Fluent theme. However you may encounter some problems with missing static resources, so you have to remember to include them in your file.
You could use the Simple theme instead of Fluent one. It uses a template with UniformGrid with 2 rows by default, but it would change the look of all controls.
So, #radoslawik proposed a good solution, but there was one problem -- he linked to nightly build of Avalonia and you may use another version. If you are you must find source code of your version (they are tagged in github) and look up styles there. For my version (0.10.18 -- it's last non-preview available at the moment) solution is next:
<Window.Styles>
<Style Selector="NumericUpDown /template/ ButtonSpinner">
<Setter Property="Template">
<ControlTemplate>
<DataValidationErrors>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
MinHeight="{TemplateBinding MinHeight}">
<DockPanel>
<UniformGrid Rows="2" Name="PART_SpinnerPanel"
DockPanel.Dock="Right"
IsVisible="{TemplateBinding ShowButtonSpinner}">
<RepeatButton Name="PART_IncreaseButton"
Classes="ButtonSpinnerRepeatButton"
VerticalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
FontSize="{TemplateBinding FontSize}">
<Path Fill="{TemplateBinding Foreground}"
Width="16"
Height="8"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{StaticResource ButtonSpinnerIncreaseButtonIcon}" />
</RepeatButton>
<RepeatButton Name="PART_DecreaseButton"
Classes="ButtonSpinnerRepeatButton"
Foreground="{TemplateBinding Foreground}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
VerticalContentAlignment="Center"
FontSize="{TemplateBinding FontSize}">
<Path Fill="{TemplateBinding Foreground}"
Width="16"
Height="8"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{StaticResource ButtonSpinnerDecreaseButtonIcon}" />
</RepeatButton>
</UniformGrid>
<ContentPresenter Name="PART_ContentPresenter"
Grid.Column="1"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Padding="{TemplateBinding Padding}" />
</DockPanel>
</Border>
</DataValidationErrors>
</ControlTemplate>
</Setter>
</Style>
</Window.Styles>

How to remove arrow from ColorCanvas dropdown control in wpf C#

I am using c# wpf ColorCanvas control for using colors in my application.I want to remove dropdown arrow from ColorCanvas control.
I am using this Xaml Code for ColorCanvas
<xctk:ColorPicker x:Name="canvas_Copy" ColorMode="ColorCanvas" VerticalAlignment="Top" Margin="93,323,409,0" />
For clarity check this image.I want to remove this Arrow form ColorCanvas.
You should use a custom ButtonStyle:
<xctk:ColorPicker x:Name="canvas_Copy" ColorMode="ColorCanvas" VerticalAlignment="Top" Margin="93,323,409,0" >
<xctk:ColorPicker.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</xctk:ColorPicker.Resources>
<xctk:ColorPicker.ButtonStyle>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton" xmlns:chrome="clr-namespace:Xceed.Wpf.Toolkit.Chromes;assembly=Xceed.Wpf.Toolkit">
<Grid SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
</Border>
<chrome:ButtonChrome x:Name="ToggleButtonChrome"
Grid.Column="1"
CornerRadius="0,2.75,2.75,0"
Visibility="{Binding ShowDropDownButton, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=xctk:ColorPicker}, Converter={StaticResource BooleanToVisibilityConverter}}"
RenderChecked="{Binding IsOpen, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=xctk:ColorPicker}}"
RenderEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=xctk:ColorPicker}}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}">
</chrome:ButtonChrome>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</xctk:ColorPicker.ButtonStyle>
</xctk:ColorPicker>
Use ColorCanvas control from the same namespace instead of ColorPicker.
finds its css file (or its styling file) and change its color to match its background

c# uwp blur part of the screen

I am using UWP Community Toolkit to create blur as following:
<Grid x:Name="gridContent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior"
Value="0"
Duration="0"
Delay="0"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
</Grid>
And this works just fine for the whole grid.
But, my problem is now that there is a listview in this grid, and I want to make custom header in that listview that will be semi transparent, and I want just content under that header to be blurred. So the content under that header will be dynamically changed.
Does anyone know how to achieve this?
Use Blur in a separate grid inside your content grid
Here is a code sample
<Grid Name="MainGrid">
<ListView>
....
</ListView>
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch">
<interactivity:Interaction.Behaviors>
<behaviors:Blur Value="25" Duration="0" Delay="0" AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
<!-- If you want color shade -->
<Grid.Background>
<SolidColorBrush Color="Red" Opacity="0.5"/>
</Grid.Background>
</Grid>
</Grid>
For more info refer UWP Hamburger Menu with Frosted glass effect
By default, the Header of the ListView is scrollable along with the content. A more elegant solution would be to extract the header template to be outside of the ScrollViewer and blur it. Note you will need to give the content a padding to give space to the header initially, and the top padding value should be equal to the height of the header.
You can do everything within a style -
<Application.Resources>
<x:Double x:Key="ListViewHeaderHeight">200</x:Double>
<Thickness x:Key="ListViewContentMargin" Top="{StaticResource ListViewHeaderHeight}"></Thickness>
<Style x:Key="BlurredHeaderListViewStyle" TargetType="ListView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<Grid BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ItemsPresenter Margin="{StaticResource ListViewContentMargin}" FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" HeaderTransitions="{TemplateBinding HeaderTransitions}" Padding="{TemplateBinding Padding}"/>
</ScrollViewer>
<ContentPresenter x:Name="HeaderPresenter" Background="Transparent" Height="{StaticResource ListViewHeaderHeight}" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" VerticalAlignment="Top">
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior" Value="12" />
</interactivity:Interaction.Behaviors>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
Now you just apply the style to any ListView you want -
<ListView Style="{StaticResource BlurredHeaderListViewStyle}">
<ListView.HeaderTemplate>
<DataTemplate>
<sampleapp:CustomHeader />
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Result

Same buttons but looks differently WPF

I have few buttons on my Window.xaml,
interesting fact is that when I run app, they are looking different even if I used same code for each of them..
Here is screenshot:
It is possible to notice that their border does not look the same (esspecialy on Y button)..
Here is my code for each custom button: (X, Y and Z)
<Button x:Name="btnX"
Grid.Column="1"
FontSize="15"
BorderThickness="1"
Content="X"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="Black"
Background="#d3d3d3"
BorderBrush="Black" Margin="5">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button x:Name="btnZ"
Grid.Column="2"
FontSize="15"
Content="Z"
BorderThickness="1"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="Black"
Background="#d3d3d3"
BorderBrush="Black" Margin="5">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button x:Name="btnY"
Grid.Column="2"
Grid.Row="1"
FontSize="15"
Content="Y"
BorderThickness="1"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="Black"
Background="#d3d3d3"
BorderBrush="Black" Margin="5">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
I find out that setting SnapsToDevicePixels="True" and UseLayoutRounding="True" on my button fixed this issue, I'm not sure if that was best answer but that definately helped me..
Buttons after setting this properties:
Borders looks same now, and black as they should be.

Display Header on Textbox only if text is set in UWP XAML

I'm trying to modify the look & feel of the textbox control in a UWP App to what our designers drawn in sketch. That includes to have a header only shown when no text is set in the textbox.
I assume that I have to modify the visibility of the HeaderContentPresenter and its DataTemplate:
<ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource TextControlHeaderForeground}" FontWeight="Normal" Margin="0,0,0,2" Grid.Row="0" x:DeferLoadStrategy="Lazy" BorderThickness="0" Visibility="Collapsed" />
I wrote an IValueConvert to convert "empty string" to visibility, but I am stuck with the binding. I can't see any way to get the datacontext.
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" Foreground="{StaticResource DarkGrey}" FontSize="10" FontFamily="TheSansB4SemiLight" Visibility="{Binding Converter={StaticResource EmptyStringToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
How can I access the text written on the textbox within the DataTemplate?
Thanks
Update with Code
I want this
MainPage.xaml
Three Textboxes I applied the same style to.
<TextBox Header="Username" PlaceholderText="Username" Grid.Column="1" HorizontalAlignment="Left" Height="67" Margin="20,143,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="295" Style="{StaticResource InputField}" />
<TextBox Header="Surname" PlaceholderText="Surname" Grid.Column="1" HorizontalAlignment="Left" Height="67" Margin="20,249,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="295" Style="{StaticResource InputField}"/>
<TextBox Header="Name" PlaceholderText="Name" Grid.Column="1" HorizontalAlignment="Left" Height="67" Margin="20,196,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="295" Style="{StaticResource InputField}"/>
Styles.xaml
Basic shareable styles within a ResourceDict, refrenced in App.xaml. When I name the textboxes "InputField", the mechanism starts working, but obviously I have name conflicts and strange behavior.
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock
Foreground="{StaticResource DarkGrey}"
FontSize="10"
FontFamily="TheSansB4SemiLight"
Visibility="{Binding Text, Converter={StaticResource EmptyStringToVisibilityConverter}, ElementName=InputField}"
Text="{Binding Header, ElementName=InputField}"
/>
</DataTemplate>
</Setter.Value>
</Setter>
Question
What element within the Template must be named to be accessible through binding? I assume it's one of the elements the textbox control is made of, but I can't find out how.
<Grid><Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1" CornerRadius="5"/>
<ContentControl x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" Foreground="{ThemeResource TextControlPlaceholderForeground}" IsHitTestVisible="False" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1"/>
<Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="2" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" VerticalAlignment="Stretch" Visibility="Collapsed"/>
<ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource TextControlHeaderForeground}" FontWeight="Normal" Margin="0,0,0,2" Grid.Row="0" x:DeferLoadStrategy="Lazy" BorderThickness="0" Visibility="Collapsed" />
<ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled" Grid.ColumnSpan="2"/>
</Grid>
There are 2 solutions here.
Hide/Show TextBox Header based on Converter and TextBox.Text Length
Hide/Show TextBox Header based on CustomControl and Lost/Gain Focus
1) Hide/Show TextBox Header based on Converter and TextBox.Text Length
You need to Name your TextBox inside DataTemplate so that binding can find the item and Process the value.
Below is a sample of Converter.
public class DataToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
Visibility dataVisible = (value.ToString().Length == 0) ? Visibility.Visible : Visibility.Collapsed;
return dataVisible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
And below is how I use it in a DataTemplate inside ListView.
<ListView ItemsSource="{Binding }">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" TextWrapping="Wrap" >
<TextBox.Header>
<TextBlock Text="Header String" Visibility="{Binding Text, Converter={StaticResource DataToVisibilityConverter}, ElementName=textBox}"/>
</TextBox.Header>
</TextBox>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Final Result
Edit
After you updated your question things got more simpler.
2. Hide/Show TextBox Header based on CustomControl and Lost/Gain Focus
You need to create a custom control to handle events that are common across for your textblock.
So as per your image, When you get focus, you show Header and lose focus, you hide it since there is text in placeholder.
Below is a custom control that does exactly that.
public sealed class MyTextBox : TextBox
{
public MyTextBox()
{
this.DefaultStyleKey = typeof(TextBox);
this.GotFocus += MyTextBox_GotFocus;
this.LostFocus += MyTextBox_LostFocus;
}
private void MyTextBox_LostFocus(object sender, RoutedEventArgs e)
{
this.Header = "";
}
private void MyTextBox_GotFocus(object sender, RoutedEventArgs e)
{
this.Header = this.PlaceholderText;
}
}
And the usage will be
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<local:MyTextBox PlaceholderText="User Name" x:Name="txtUserName" Grid.Row="0" Margin="10"/>
<local:MyTextBox PlaceholderText="Email" x:Name="txtEmail" Grid.Row="1" Margin="10"/>
<local:MyTextBox PlaceholderText="Password" x:Name="txtPassword" Grid.Row="2" Margin="10"/>
</Grid>

Categories