• 【WPF系列】Textbox


    Style定义实例

    给Textbox定义一个阴影效果。

    <Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
             <Setter Property="SnapsToDevicePixels" Value="True"/>
             <Setter Property="OverridesDefaultStyle" Value="True"/>
             <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
             <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
             <Setter Property="MinWidth" Value="120"/>
             <Setter Property="MinHeight" Value="20"/>
             <Setter Property="AllowDrop" Value="true"/>
             <Setter Property="Template">
                <Setter.Value>
                   <ControlTemplate TargetType="{x:Type TextBoxBase}">
                   <Border x:Name="Border"                                              
                         BorderThickness="1"
                         CornerRadius="2"
                         Padding="0">
                         <Border.BorderBrush>
                         <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="#888888" Offset="0" />
      <GradientStop Color="#AAAAAA" Offset=".2" />
    </LinearGradientBrush>
                         </Border.BorderBrush>
                         <ScrollViewer x:Name="PART_ContentHost" Margin="0">
                            <ScrollViewer.Background>
                               <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                  <GradientStop Offset="0" Color="WhiteSmoke"/>
                                  <GradientStop Offset="1" Color="LightGray"/>
                               </LinearGradientBrush>
                            </ScrollViewer.Background>
                         </ScrollViewer>
                      </Border>
                     
                      <ControlTemplate.Triggers>
                         <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
                            <Setter TargetName="Border" Property="BorderBrush" Value="#EEEEEE"/>
                            <Setter Property="Foreground" Value="#888888"/>
                         </Trigger>
                      </ControlTemplate.Triggers>
                   </ControlTemplate>
                </Setter.Value>
             </Setter>
          </Style>

    UpdateSourceTrigger

    默认UpdateSourceTrigger为LostFoucs,有时需要及时CommitValue,则需要设置为PropertyChanged。这样当Text属性的值发生变化时,我们的值就能及时更新到Datasource中。

    更多参考

    How to: Control When the TextBox Text Updates the Source

    NumberTextbox

    1. 使用NubmberTextboxBehavior
    2. 将TextBox的binding属性中Delay设置为1000
    <Binding Path="UpperLeftCornerLatitude" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" Delay="1000">
    </Binding>
    //NumericTextBoxBehavior
    /// <summary>
        /// This forces a TextBoxBase control to be numeric-entry only
        /// </summary>
        /// <example>
        /// <![CDATA[  <TextBox Cinch:NumericTextBoxBehavior.IsEnabled="True" />  ]]>
        /// </example>
        public static class NumericTextBoxBehavior
        {
            #region IsEnabled DP
            /// <summary>
            /// Dependency Property for turning on numeric behavior in a TextBox.
            /// </summary>
            public static readonly DependencyProperty IsEnabledProperty =
                DependencyProperty.RegisterAttached("IsEnabled",
                    typeof(bool), typeof(NumericTextBoxBehavior),
                        new UIPropertyMetadata(false, OnEnabledStateChanged));
    
            /// <summary>
            /// Attached Property getter for the IsEnabled property.
            /// </summary>
            /// <param name="source">Dependency Object</param>
            /// <returns>Current property value</returns>
            public static bool GetIsEnabled(DependencyObject source)
            {
                return (bool)source.GetValue(IsEnabledProperty);
            }
    
            /// <summary>
            /// Attached Property setter for the IsEnabled property.
            /// </summary>
            /// <param name="source">Dependency Object</param>
            /// <param name="value">Value to set on the object</param>
            public static void SetIsEnabled(DependencyObject source, bool value)
            {
                source.SetValue(IsEnabledProperty, value);
            }
    
            /// <summary>
            /// This is the property changed handler for the IsEnabled property.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private static void OnEnabledStateChanged(DependencyObject sender,
                DependencyPropertyChangedEventArgs e)
            {
                TextBox tb = sender as TextBox;
                if (tb == null)
                    return;
    
                tb.PreviewTextInput -= tbb_PreviewTextInput;
                DataObject.RemovePastingHandler(tb, OnClipboardPaste);
    
                bool b = ((e.NewValue != null && e.NewValue.GetType() == typeof(bool))) ?
                    (bool)e.NewValue : false;
                if (b)
                {
                    tb.PreviewTextInput += tbb_PreviewTextInput;
                    DataObject.AddPastingHandler(tb, OnClipboardPaste);
                }
            }
    
            #endregion
    
            #region Private Methods
    
            /// <summary>
            /// This method handles paste and drag/drop events
            /// onto the TextBox. It restricts the character
            /// set to numerics and ensures we have consistent behavior.
            /// </summary>
            /// <param name="sender">TextBox sender</param>
            /// <param name="e">EventArgs</param>
            private static void OnClipboardPaste(object sender, DataObjectPastingEventArgs e)
            {
                TextBox tb = sender as TextBox;
                string text = e.SourceDataObject.GetData(e.FormatToApply) as string;
    
                if (tb != null && !string.IsNullOrEmpty(text) && !Validate(tb, text))
                    e.CancelCommand();
            }
    
            /// <summary>
            /// This checks if the resulting string will match the regex expression
            /// </summary>
            static void tbb_PreviewTextInput(object sender, TextCompositionEventArgs e)
            {
                TextBox tb = sender as TextBox;
    
                if (tb != null && !Validate(tb, e.Text))
                    e.Handled = true;
            }
    
            #endregion
    
            private static bool Validate(TextBox tb, string newContent)
            {
                string testString = string.Empty;
                // replace selection with new text.
                if (!string.IsNullOrEmpty(tb.SelectedText))
                {
                    string pre = tb.Text.Substring(0, tb.SelectionStart);
                    string after = tb.Text.Substring(tb.SelectionStart + tb.SelectionLength,
                                   tb.Text.Length - (tb.SelectionStart + tb.SelectionLength));
                    testString = pre + newContent + after;
                }
                else
                {
                    string pre = tb.Text.Substring(0, tb.CaretIndex);
                    string after = tb.Text.Substring(tb.CaretIndex,
                                           tb.Text.Length - tb.CaretIndex);
                    testString = pre + newContent + after;
                }
    
                Regex regExpr = new Regex(@"^([-+]?)(d*)([,.]?)(d*)$");
                if (regExpr.IsMatch(testString))
                    return true;
    
                return false;
            }
        }

    WaterMark/HintText/PlaceHoder

    1. 通过Style
    2. 通过AttachBehavior
    3. 通过自定义控件

    1.给TextBox添加水印效果(提示文字)

    <!--Add a placeHolder for TextBox using Tag value-->
        <Style x:Key="placeHolder" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Grid>
                            <TextBox Text="{Binding Path=Text,
                                                    RelativeSource={RelativeSource TemplatedParent},
                                                    Mode=TwoWay,
                                                    UpdateSourceTrigger=PropertyChanged,
                                                    Delay=1000}"
                                     x:Name="textSource"
                                     Background="Transparent"
                                     Panel.ZIndex="2" />
                            <TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
                                <TextBox.Style>
                                    <Style TargetType="{x:Type TextBox}">
                                        <Setter Property="Foreground" Value="Transparent" />
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
                                                <Setter Property="Foreground" Value="LightGray" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </TextBox.Style>
                            </TextBox>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    2.通过AttachBehavior

    3.通过自定义控件

      参考

      WPF validation rule preventing decimal entry in textbox?

      Set WPF Binding.StringFormat Property on TextBox via Style

    1. 相关阅读:
      antd表单不显示label和冒号
      create-react-app 区分环境 环境变量
      在actionCreator中使用getState,数据格式是immutable
      给树状数据添加层级id
      vscode中的正则搜索与替换演示,删除对象中不要的属性及属性值
      http-proxy-middleware做代理时,自定义复杂的匹配规则
      antd省市区级联
      axios封装
      jmeter-07-参数化-关联(json提取)
      jmeter-06-参数化-csv参数化
    2. 原文地址:https://www.cnblogs.com/HQFZ/p/4313001.html
    Copyright © 2020-2023  润新知