【c#】文本控件

一、TextBlock

1、分行

1.1 若内容超过长度,自动分行

TextWrapping="Wrap" 

1.2 自定义分行

//文本内容使用Environment.NewLine进行拼接
this.tb.Text = "第一行内容"+ Environment.NewLine + "第二行内容";

2、截断省略

2.1

TextTrimming="CharacterEllipsis" 

2.2 使用时需禁止Wrap,默认为NoWrap

TextWrapping="Wrap" 

二、TextBox

1、一些属性

1.1 内容垂直对齐方式,默认为Top

VerticalContentAlignment="Top"//Center,Bottom,Stretch

1.2 最大长度

MaxLength = "";//中文、英文、其他符号都只占一个长度

1.3 文本自动换行

TextWrapping="Wrap"

1.4 Enter换行

AcceptsReturn="True"

2、样式

2.1 普通圆角

<Style TargetType="TextBox" x:Key="ThisTextBoxStyle">
     <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate>
                 <Border x:Name="border" CornerRadius="5" BorderBrush="#CCCCCC" BorderThickness="1" Padding="0,2" Height="{Binding Width, RelativeSource={RelativeSource Self}}" Background="{TemplateBinding Background}">
                     <ScrollViewer VerticalAlignment="Top" x:Name="PART_ContentHost" DockPanel.Dock="Left" Background="{TemplateBinding Background}" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled"/>
                 </Border>
                 <ControlTemplate.Triggers>
                     <DataTrigger Binding="{Binding IsReadOnly,RelativeSource={RelativeSource Self}}" Value="true">
                         <Setter Property="Background" Value="#f0f0f0">
                         </Setter>
                     </DataTrigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

在这里插入图片描述

三、RichTextBox

1、

1.1

四、Placeholder

1、

1.1

五、一些示例

1、TextBoxWithErrorPop 带错误提示框的textBox

1.1 xaml

 <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Height" Value="32"></Setter>
            <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <StackPanel>
                            <Border x:Name="border" BorderBrush="#d6d6d6" BorderThickness="1" CornerRadius="5" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
                                <Grid>
                                    <TextBox x:Name="InTb" AcceptsReturn="True" Margin="4,0" Width="auto" Height="auto" BorderThickness="0" Text="{Binding Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" FontSize="{TemplateBinding FontSize}" Background="{Binding Background,ElementName=border}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" MaxLength="{Binding MaxLength}" Visibility="Visible" TextWrapping="{Binding TextWrapping}"></TextBox>
                                </Grid>
                            </Border>
                            <common:PopupNonTopmost IsOpen="{Binding ErrOpen}" StaysOpen="True" x:Name="Pop_Err"
                                   Placement="Bottom"  PlacementTarget="{Binding ElementName=border}"
                                   AllowsTransparency="True" IsTopmost="False" HorizontalAlignment="Left">
                                <local:ErrorInfoPop  Height="32" Width="250" Tag="{TemplateBinding Tag}" ></local:ErrorInfoPop>
                            </common:PopupNonTopmost>
                            <!--<Popup AllowsTransparency="True" IsOpen="False" x:Name="Pop_Err">
                                <local:ErrorInfoPop  Height="32" Width="250" Tag="{TemplateBinding Tag}"></local:ErrorInfoPop>
                            </Popup>-->
                        </StackPanel>
                        <ControlTemplate.Triggers>
                            <Trigger Property="VerticalContentAlignment" Value="top">
                                <Setter Property="Margin" TargetName="InTb" Value="4,6"></Setter>
                            </Trigger>
                            <DataTrigger Binding="{Binding ErrOpen,RelativeSource={RelativeSource Self}}" Value="false">
                                <Setter Property="BorderBrush" TargetName="border" Value="#d6d6d6"></Setter>
                            </DataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition  Binding="{Binding IsReadOnly,RelativeSource={RelativeSource Self}}" Value="false"></Condition>
                                    <Condition Binding="{Binding IsFocused,RelativeSource={RelativeSource Self}}" Value="true"></Condition>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="BorderBrush" TargetName="border" Value="#076ff5"></Setter>
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition  Binding="{Binding IsReadOnly,RelativeSource={RelativeSource Self}}" Value="false"></Condition>
                                    <Condition Binding="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}" Value="true"></Condition>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="BorderBrush" TargetName="border" Value="#076ff5"></Setter>
                            </MultiDataTrigger>
                            <DataTrigger Binding="{Binding IsReadOnly,RelativeSource={RelativeSource Self}}" Value="true">
                                <Setter Property="Background" TargetName="border" Value="#f5f5f5"></Setter>
                                <Setter Property="BorderBrush" TargetName="border" Value="#d6d6d6"></Setter>
                                <Setter Property="Foreground" Value="#b3b3b3"></Setter>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding ErrOpen,RelativeSource={RelativeSource Self}}" Value="True">
                                <Setter Property="BorderBrush" TargetName="border" Value="#ff3939"></Setter>
                            </DataTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TextBox.Style>

1.2 cs

public partial class TextBoxWithErrorPop : TextBox,INotifyPropertyChanged
    {
        public bool _ErrOpen = false;
        public bool ErrOpen { get { return _ErrOpen; } set { _ErrOpen = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ErrOpen")); } }
        public ScrollContentPresenter ParentSv;
        public Window ParentWin;
        public TextBoxWithErrorPop()
        {
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            ErrOpen = false;
        }

        public void TextBox_Loaded(object sender, RoutedEventArgs e)
        {
            ParentSv = TryGetParent<ScrollContentPresenter>(this);
            ParentWin = TryGetParent<Window>(this);
            if (ParentSv != null)
            {
                ParentSv.ScrollOwner.ScrollChanged += (s, ea) =>
                {
                    if (ErrOpen)
                    {
                        ErrOpen = false;
                    }
                };
            }
            if (ParentWin != null)
            {
                ParentWin.LocationChanged += (s,ea) =>
                {
                    if (ErrOpen)
                    {
                        ErrOpen = false;
                    }
                };
            }
        }

        public T TryGetParent<T>(DependencyObject element)
            where T : DependencyObject
        {
            if (element == null)
                return null;
            DependencyObject parent = VisualTreeHelper.GetParent(element);
            if (parent == null)
                return null;
            T parentTr = parent as T;
            if (parentTr != null)
                return parentTr;
            return TryGetParent<T>(parent);
        }
    }

1.3 PopupNonTopmost【Topmost = false】

class PopupNonTopmost : Popup
    {
        /// <summary>
        /// Is Topmost dependency property
        /// </summary>
        public static readonly DependencyProperty IsTopmostProperty = DependencyProperty.Register("IsTopmost", typeof(bool), typeof(PopupNonTopmost), new FrameworkPropertyMetadata(false, OnIsTopmostChanged));

        private bool? _appliedTopMost;
        private bool _alreadyLoaded;
        private Window _parentWindow;

        /// <summary>
        /// Get/Set IsTopmost
        /// </summary>
        public bool IsTopmost
        {
            get { return (bool)GetValue(IsTopmostProperty); }
            set { SetValue(IsTopmostProperty, value); }
        }

        /// <summary>
        /// ctor
        /// </summary>
        public PopupNonTopmost()
        {
            Loaded += OnPopupLoaded;
            Unloaded += OnPopupUnloaded;
        }


        void OnPopupLoaded(object sender, RoutedEventArgs e)
        {
            if (_alreadyLoaded)
                return;

            _alreadyLoaded = true;

            if (Child != null)
            {
                Child.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(OnChildPreviewMouseLeftButtonDown), true);
            }

            _parentWindow = Window.GetWindow(this);

            if (_parentWindow == null)
                return;

            _parentWindow.Activated += OnParentWindowActivated;
            _parentWindow.Deactivated += OnParentWindowDeactivated;
        }

        private void OnPopupUnloaded(object sender, RoutedEventArgs e)
        {
            if (_parentWindow == null)
                return;
            _parentWindow.Activated -= OnParentWindowActivated;
            _parentWindow.Deactivated -= OnParentWindowDeactivated;
        }

        void OnParentWindowActivated(object sender, EventArgs e)
        {
            SetTopmostState(true);
        }

        void OnParentWindowDeactivated(object sender, EventArgs e)
        {
            if (IsTopmost == false)
            {
                SetTopmostState(IsTopmost);
            }
        }

        void OnChildPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {

            SetTopmostState(true);

            if (!_parentWindow.IsActive && IsTopmost == false)
            {
                _parentWindow.Activate();
            }
        }

        private static void OnIsTopmostChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var thisobj = (PopupNonTopmost)obj;

            thisobj.SetTopmostState(thisobj.IsTopmost);
        }

        protected override void OnOpened(EventArgs e)
        {
            //_appliedTopMost = null;
            SetTopmostState(IsTopmost);
            base.OnOpened(e);
        }

        private void SetTopmostState(bool isTop)
        {
            // Don’t apply state if it’s the same as incoming state
            if (_appliedTopMost.HasValue && _appliedTopMost == isTop)
            {
                return;
            }

            if (Child == null)
                return;

            var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource;

            if (hwndSource == null)
                return;
            var hwnd = hwndSource.Handle;

            RECT rect;

            if (!GetWindowRect(hwnd, out rect))
                return;

            if (isTop)
            {
                SetWindowPos(hwnd, HWND_TOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
            }
            else
            {
                // Z-Order would only get refreshed/reflected if clicking the
                // the titlebar (as opposed to other parts of the external
                // window) unless I first set the popup to HWND_BOTTOM
                // then HWND_TOP before HWND_NOTOPMOST
                SetWindowPos(hwnd, HWND_BOTTOM, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
                SetWindowPos(hwnd, HWND_TOP, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
                SetWindowPos(hwnd, HWND_NOTOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
            }

            _appliedTopMost = isTop;
        }

        #region P/Invoke imports & definitions
        #pragma warning disable 1591 //Xml-doc
        #pragma warning disable 169 //Never used-warning
        // ReSharper disable InconsistentNaming
        // Imports etc. with their naming rules

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT

        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        [DllImport("user32.dll")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
        int Y, int cx, int cy, uint uFlags);

        static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
        static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
        static readonly IntPtr HWND_TOP = new IntPtr(0);
        static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

        private const UInt32 SWP_NOSIZE = 0x0001;
        const UInt32 SWP_NOMOVE = 0x0002;
        const UInt32 SWP_NOZORDER = 0x0004;
        const UInt32 SWP_NOREDRAW = 0x0008;
        const UInt32 SWP_NOACTIVATE = 0x0010;

        const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
        const UInt32 SWP_SHOWWINDOW = 0x0040;
        const UInt32 SWP_HIDEWINDOW = 0x0080;
        const UInt32 SWP_NOCOPYBITS = 0x0100;
        const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don’t do owner Z ordering */
        const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don’t send WM_WINDOWPOSCHANGING */

        const UInt32 TOPMOST_FLAGS =
            SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSENDCHANGING;

        // ReSharper restore InconsistentNaming
        #pragma warning restore 1591
        #pragma warning restore 169
        #endregion
    }

1.4 使用时在cs中ErrOpen = true 即可展示错误info,效果如下;窗口locationChanged 或ScrollChanged时会自动消失
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值