c# - 如何在通用 Windows 10 应用程序中自定义文本框的边框和背景?

标签 c# xaml uwp windows-10-universal uwp-xaml

我正在开发一个通用的 Windows 10 应用程序。我想自定义一个文本框以删除其默认边框悬停和背景。

我的问题是我不知道如何在通用 Windows 平台上进行自定义。

这是我使用的代码:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <!--layoutroot where all page content is placed-->
    <Grid x:Name="layoutRoot" Background="#1BA1E2">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0" Margin="12,0,12,0">
            <!--Title Page-->
            <TextBlock Text="Login Here" Foreground="White" FontSize="40" Padding="60,80,60,80"/>

            <!--username-->
            <Border CornerRadius="10" Background="Transparent" BorderBrush="White" BorderThickness="1" Margin="5">
                <TextBox PlaceholderText="Username" Name="Username" Background="Transparent" BorderBrush="{x:Null}" GotFocus="Username_GotFocus"/>
            </Border>
            <!--Password-->
            <Border CornerRadius="10" Background="Transparent" BorderBrush="White" BorderThickness="1" Margin="5">
                <TextBox PlaceholderText="Password" Name="Password" Background="Transparent" BorderBrush="{x:Null}" GotFocus="Password_GotFocus"/>
            </Border>

            <!--Button login-->
            <Border CornerRadius="10" Background="Transparent" BorderBrush="White" BorderThickness="1" Margin="5">
                <TextBlock Text="Log In" Foreground="White" Margin="0" Padding="200,5,0,5"/>
            </Border>

        </StackPanel><!--end StackPanel-->
    </Grid><!--end Grid layoutRoot-->
</Grid>

这是我的 UI 问题的屏幕截图:

当我将鼠标指针放在文本框上时,它会更改边框和背景。

screenshot

最佳答案

自定义TextBox , 我们可以编辑 TextBox styles and templates .

首先,我们可以在Visual Studio中打开“Document Outline”,方法是打开“View”→“Other Windows”→“Document Outline”

然后在“Document Outline”中选择我们要修改的TextBox,例如选择“Username”并右击,然后选择“编辑模板”→“编辑副本...”

这将弹出一个“创建样式资源”对话框。默认情况下,它会在 Page.Resources 下生成默认样式,例如:

<Page.Resources>
    <Style x:Key="TextBoxStyle1" TargetType="TextBox">
    ...
    </Style>
</Page.Resources>

在此之后我们可以编辑样式和模板来实现我们想要的。

悬停样式定义在"PointerOver" VisualState .

<VisualState x:Name="PointerOver">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}"/>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BorderElement">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundPointerOver}"/>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundPointerOver}"/>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}"/>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState> 

要删除它的默认边框和背景,我们只需删除动画目标 BorderBrushBackground 就像:

<VisualState x:Name="PointerOver">
    <Storyboard>
        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundPointerOver}" />
        </ObjectAnimationUsingKeyFrames>-->
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlPlaceholderForegroundPointerOver}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

"Focused" VisualState 是一样的。

此外,在默认模板中,您会发现TextBox中已经有一个Border

<Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1"/>

所以我们可以在这个Border中添加CornerRadius="10":

<Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1" `CornerRadius="10"`/>

然后在 TextBox 中使用这种新样式,无需额外的 Border,例如:

<StackPanel Grid.Row="0" Margin="12,0,12,0">
    <!--  Title Page  -->
    <TextBlock FontSize="40" Foreground="White" Padding="60,80,60,80" Text="Login Here" />

    <!--  username  -->
    <TextBox Name="Username" Margin="5" Background="Transparent" BorderBrush="White" GotFocus="Username_GotFocus" PlaceholderText="Username" Style="{StaticResource TextBoxStyle1}" />
...
</StackPanel>

如果要将此样式应用到 Page 中的所有 TextBox,可以删除 x:Key="TextBoxStyle1" Style 并且不设置 TextBoxStyle 属性:

<Page.Resources>
    <Style TargetType="TextBox">
    ...
    </Style>
</Page.Resources>

这样,该样式将自动应用于 Page 中的所有 TextBox

关于c# - 如何在通用 Windows 10 应用程序中自定义文本框的边框和背景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40135914/

相关文章:

c# - 在C#中加载COM对象会引发 “Unable to cast COM object of type ' System .__ ComObject'异常到接口(interface)类型…”,但C++或VB不会

c# - 在 StaticResource Canvas 中为 Path 设置不同的大小或自动调整大小

wpf - slider 不适用于触摸输入

html - WPF 中 HTML 类 ID 的等价物是什么?

c++ - 如何在 C++/WinRT (`Promise.all` 等效项中等待多个可等待/IAsyncActions)?

c# - lambda 表达式中的枚举的编译方式不同;重载分辨率改进的结果?

c# - "SaveAs"Wordprocessingdocument (Open XML) 文件被锁定

c# - 隐藏/显示 XAML 元素或阻止 LostFocus 事件

c# - ContentDialog showAsync() 给出错误 : no definition for getAwaiter

c# - 带有字形信息的字体渲染