RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 892772
Accepted
Павел Ериков
Павел Ериков
Asked:2020-10-14 03:14:11 +0000 UTC2020-10-14 03:14:11 +0000 UTC 2020-10-14 03:14:11 +0000 UTC

自定义控件 c# WPF

  • 772

如何制作像 PasswordBox 这样的自定义控件,其中密码框左侧会有一个文本块(锁定图标或其他符号)a。也就是说,将密码框和文本块组合成 1 个控件。我可以从中获取密码值。有一个想法让 PasswordBox a ControlTemplate из textblocka 和 passwordbox`a 但我还需要能够更改 MainWindow.xaml 中的样式

cs:CustomPassBox Style={StaticResource DefaultStyle}>

但是当我像这样设置控件样式时, controlTemplate 消失了。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    EvgeniyZ
    2020-10-14T19:39:58Z2020-10-14T19:39:58Z

    好吧,看,主要目标是将两个元素合二为一,并添加使用样式的能力。你可以走几种方式。

    使用样式:

    这里的重点是,我们制作了一些基本样式,在其中重新定义了我们需要的内容并添加了新样式。

    例如,我们有这种风格PasswordBox:

    <Style x:Key="MainStyle" TargetType="PasswordBox">
        <Setter Property="Height" Value="30"/>
        <Setter Property="Width" Value="150"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Viewbox>
                            <Canvas Width="24" Height="24">
                                <Path Data="M12,17C10.89,17 10,16.1 10,15C10,13.89 10.89,13 12,13A2,2 0 0,1 14,15A2,2 0 0,1 12,17M18,20V10H6V20H18M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10C4,8.89 4.89,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z" Fill="Black" />
                            </Canvas>
                        </Viewbox>
                        <Border Grid.Column="1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    应用后,我们得到以下结果:

    <PasswordBox Style="{StaticResource MainStyle}" Password="1234" />
    

    结果 1

    现在,假设我们要设置某种样式,例如,对于错误,然后我们创建另一种样式并将其设置为BaseOn,它将继承基本样式的所有内容:

    <Style x:Key="ErrorStyle" TargetType="PasswordBox" BasedOn="{StaticResource MainStyle}">
        <Setter Property="Background" Value="#99DE0000"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
    

    应用并查看结果:

    <PasswordBox Style="{StaticResource ErrorStyle}" Password="1234" />
    

    结果 2

    使用用户控件:

    这里的一切都差不多,但也有这样的事情DependencyProperty。在它的帮助下,我们可以将非标准属性传递给我们的控件(例如,我们PasswordBox有一个属性Password,我们也可以这样做,但假设要覆盖图标),UserControl 也支持样式。让我们创建一些简单的东西:

    添加具有此样式的 UserControl:

    <UserControl x:Class="WpfApp1.CustomPasswordBox"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApp1"
                 mc:Ignorable="d" 
                 x:Name="uc"
                 Height="30" Width="150">
        <UserControl.Resources>
            <StreamGeometry x:Key="DefaultData">
                M12,17C10.89,17 10,16.1 10,15C10,13.89 10.89,13 12,13A2,2 0 0,1 14,15A2,2 0 0,1 12,17M18,20V10H6V20H18M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10C4,8.89 4.89,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z
            </StreamGeometry>
        </UserControl.Resources>
        <UserControl.Template>
            <ControlTemplate TargetType="UserControl">
                <ContentPresenter/>
            </ControlTemplate>
        </UserControl.Template>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Viewbox>
                <Canvas Width="24" Height="24">
                    <Path Data="{Binding ElementName=uc, Path=Icon, FallbackValue={StaticResource DefaultData}, TargetNullValue={StaticResource DefaultData}}" Fill="Black" />
                </Canvas>
            </Viewbox>
            <PasswordBox x:Name="PBox" Grid.Column="1" Foreground="{Binding ElementName=uc, Path=Foreground}" Background="{Binding ElementName=uc, Path=Background}" VerticalContentAlignment="Center" />
        </Grid>
    </UserControl>
    

    并定义一对 DP:

    public partial class CustomPasswordBox : UserControl
    {
        public CustomPasswordBox()
        {
            InitializeComponent();
    
            PBox.PasswordChanged += (sender, args) => {
                Password = ((PasswordBox) sender).SecurePassword;
            };
        }
    
        public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register(
            "Password", typeof(SecureString), typeof(CustomPasswordBox), new PropertyMetadata(default(SecureString)));
    
        public SecureString Password
        {
            get => (SecureString)GetValue(PasswordProperty);
            set => SetValue(PasswordProperty, value);
        }
    
        public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
            "Icon", typeof(StreamGeometry), typeof(CustomPasswordBox), new PropertyMetadata(default(StreamGeometry)));
    
        public StreamGeometry Icon
        {
            get => (StreamGeometry) GetValue(IconProperty);
            set => SetValue(IconProperty, value);
        }
    }
    

    在这里,例如,我设置了两个 DependencyProperty:

    1. 密码 - 这里有一些困难,更准确地说,在 WPF 中,密码不应该以不受保护的形式存储在内存中,因此无法简单地绑定密码,您必须通过PasswordChanged事件传递它. 互联网上有很多关于如何解决这个问题的例子,这会很有趣,我想你会发现......
    2. 图标 - 我们的矢量图标的简单几何形状。

    现在让我们调用它并查看结果:

    <local:CustomPasswordBox />
    

    加州大学成绩

    让我们为新的 UserControl 创建一个样式,覆盖颜色和图标:

    <StreamGeometry x:Key="KeyIcon">
        M21,11C21,16.55 17.16,21.74 12,23C6.84,21.74 3,16.55 3,11V5L12,1L21,5V11M12,21C15.75,20 19,15.54 19,11.22V6.3L12,3.18L5,6.3V11.22C5,15.54 8.25,20 12,21M12,6A3,3 0 0,1 15,9C15,10.31 14.17,11.42 13,11.83V14H15V16H13V18H11V11.83C9.83,11.42 9,10.31 9,9A3,3 0 0,1 12,6M12,8A1,1 0 0,0 11,9A1,1 0 0,0 12,10A1,1 0 0,0 13,9A1,1 0 0,0 12,8Z
    </StreamGeometry>
    
    <Style x:Key="ErrorStyle" TargetType="local:CustomPasswordBox">
        <Setter Property="Background" Value="#99DE0000"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Icon" Value="{StaticResource KeyIcon}"/>
    </Style>
    

    结果:

    <local:CustomPasswordBox Style="{StaticResource ErrorStyle}" />
    

    UC结果2

    实际上,这就是我们可以非常简单地使用元素的方式。
    祝你学习 WPF 好运!

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5