仅当在UWP XAML中设置文本时,才在文本框上显示标题

时间:2017-01-16 15:15:33

标签: c# xaml uwp

我试图修改外观&感觉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中文本框上写的文本?

由于

使用代码更新

我想要这个 SampleControl

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>

1 个答案:

答案 0 :(得分:2)

  

这里有两个解决方案。

     
      
  1. 隐藏/显示基于Converter和TextBox.Text长度的TextBox标题
  2.   
  3. 隐藏/显示基于CustomControl和Lost / Gain Focus的TextBox标题
  4.   

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>

最终结果

enter image description here

修改

更新问题后,事情变得更加简单。

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