我试图修改外观&感觉UWP App中的文本框控件是我们的设计师在草图中绘制的。这包括仅在文本框中未设置文本时显示标题。
我假设我必须修改HeaderContentPresenter及其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" />
我写了一个IValueConvert转换&#34;空字符串&#34;能见度,但我坚持绑定。我无法找到任何获取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>
如何访问DataTemplate中文本框上写的文本?
由于
MainPage.xaml中
我使用相同的样式的三个文本框。
<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
ResourceDict中的基本可共享样式,在App.xaml中引用。当我命名文本框&#34; InputField&#34;时,机制开始工作,但显然我有名称冲突和奇怪的行为。
<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>
问题
必须将模板中的哪个元素命名为可通过绑定访问?我认为它是文本框控件的组成部分之一,但我无法知道如何。
<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>
答案 0 :(得分:2)
这里有两个解决方案。
- 隐藏/显示基于Converter和TextBox.Text长度的TextBox标题
- 隐藏/显示基于CustomControl和Lost / Gain Focus的TextBox标题
醇>
1)隐藏/显示基于Converter和TextBox.Text长度的TextBox标题
您需要在TextBox
内命名DataTemplate
,以便绑定可以找到该项并处理该值。
以下是转换器的示例。
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();
}
}
以下是我在ListView
内的 DataTemplate 中使用它的方法。
<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>
最终结果
修改强>
更新问题后,事情变得更加简单。
<强> 2。隐藏/显示基于CustomControl和Lost / Gain Focus的TextBox标题
您需要创建一个自定义控件来处理文本块中常见的事件。
根据您的图像,当您获得焦点时,显示标题并失去焦点,您将其隐藏,因为占位符中有文本。
下面是一个完全相同的自定义控件。
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;
}
}
用法将是
<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>