wpf 自定义mask datepicker

注意如果设置了系统dateformat格式。在变化系统culture的时候需要设置dateformat

 CultureInfo info = new CultureInfo(this.LanguageItems[value].Name);
            info.DateTimeFormat.ShortDatePattern= "dd/MM/yyyy";          
  info.DateTimeFormat.LongDatePattern = "dd/MM/yyyy";                 Thread.CurrentThread.CurrentCulture = info;
            Thread.CurrentThread.CurrentUICulture = info;
View Code

 

 

在textbox中设置

InputMethod.IsInputMethodEnabled=“false”;可以禁止textbox禁用IME开关,(做到不允许中文字符的输入)

 

  //   若要将光标置于 TextBox 控件的内容的开头,应调用 Select 方法,并指定选择内容的起始位置为 0,选择长度为 0。
        //1 textBox1.Select(0, 0);
        //若要将光标置于 TextBox 控件的内容的末尾,应调用 Select 方法,并指定选择内容的起始位置等于文本内容的长度,选择长度为 0。
        //1 textBox1.Select(textBox1.Text.Length, 0);
        //若要将光标置于 TextBox 控件的内容的当前位置,应调用 Select 方法,并指定选择内容的起始位置等于光标的当前位置,选择长度为 0。
        //1 textBox1.Select(textBox1.SelectionStart, 0);


        //原因是通过鼠标让TextBox获得输入焦点时,TextBox触发的事件顺序是:MouseDown->GotFocus->MouseUp,
        // 也就是说TextBox在鼠标按下的那一刻已经获得了输入焦点,此时可以对Select(0, 0)设置焦点位置。
        // 但郁闷的是,MouseUp却会取消TextBox状态...也就是说文本焦点其实曾经被设置了,但立即又被取消(-_-#)

 textbox 用鼠标获得焦点的顺序是 mouseDown  GotFocus  mouseUP.  mouseup会把gotFocus设置的select取消

 

View Code
  private void MyTextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            this.MyTextBox.Tag = true;
            if (this.SelectedDate != null)
            {
                this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault());
            }
            else
            {
                UpdateInputMask();
               // this.MyTextBox.Text = "__/__/____";
                this.MyTextBox.Select(0, 0);

            }

        }

所有在mouseup的时候要设置

 

View Code
   private void MyTextBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (this.SelectedDate==null)
            {
                if (e.ChangedButton == MouseButton.Left && (bool)this.MyTextBox.Tag == true)
                {
                    this.MyTextBox.Select(0, 0);
                }
                this.MyTextBox.Tag = false;

            }
            
          
        }

使用tag来标记。。是否是左击鼠标获得焦点。。获得之后就不在设置焦点位置

 

 

样式

View Code
   <!--Control colors.-->
        <Color x:Key="WindowColor">#FFE8EDF9</Color>
        <Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
        <Color x:Key="ContentAreaColorDark">#FF7381F9</Color>

        <Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
        <Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
        <Color x:Key="DisabledForegroundColor">#FF888888</Color>

        <Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
        <Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>

        <Color x:Key="ControlLightColor">White</Color>
        <Color x:Key="ControlMediumColor">#FF7381F9</Color>
        <Color x:Key="ControlDarkColor">#FF211AA9</Color>

        <Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
        <Color x:Key="ControlPressedColor">#FF211AA9</Color>


        <Color x:Key="GlyphColor">#FF444444</Color>
        <Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>

        <!--Border colors-->
        <Color x:Key="BorderLightColor">#FFCCCCCC</Color>
        <Color x:Key="BorderMediumColor">#FF888888</Color>
        <Color x:Key="BorderDarkColor">#FF444444</Color>

        <Color x:Key="PressedBorderLightColor">#FF888888</Color>
        <Color x:Key="PressedBorderDarkColor">#FF444444</Color>

        <Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
        <Color x:Key="DisabledBorderDarkColor">#FF888888</Color>

        <Color x:Key="DefaultBorderBrushDarkColor">Black</Color>

        <!--Control-specific resources.-->
        <Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
        <Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
        <Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>

        <Color x:Key="NavButtonFrameColor">#FF3843C4</Color>

        <LinearGradientBrush x:Key="MenuPopupBrush"
                     EndPoint="0.5,1"
                     StartPoint="0.5,0">
            <GradientStop Color="{DynamicResource ControlLightColor}"
                Offset="0" />
            <GradientStop Color="{DynamicResource ControlMediumColor}"
                Offset="0.5" />
            <GradientStop Color="{DynamicResource ControlLightColor}"
                Offset="1" />
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
                     StartPoint="0,0"
                     EndPoint="1,0">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#000000FF"
                    Offset="0" />
                    <GradientStop Color="#600000FF"
                    Offset="0.4" />
                    <GradientStop Color="#600000FF"
                    Offset="0.6" />
                    <GradientStop Color="#000000FF"
                    Offset="1" />
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <Style x:Key="DatePickerCalendarStyle"
       TargetType="{x:Type Calendar}"
       BasedOn="{StaticResource {x:Type Calendar}}" />

        <!--The template for the button that displays the calendar.-->
        <Style x:Key="DropDownButtonStyle"
       TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0" />
                                        <VisualTransition GeneratedDuration="0:0:0.1"
                                  To="MouseOver" />
                                        <VisualTransition GeneratedDuration="0:0:0.1"
                                  To="Pressed" />
                                    </VisualStateGroup.Transitions>
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver">
                                        <!--<Storyboard>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#F2FFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[2].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#CCFFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                        <ColorAnimation Duration="0"
                                  To="#FF448DCA"
                                  Storyboard.TargetProperty="(Border.Background).                             (SolidColorBrush.Color)"
                                  Storyboard.TargetName="Background" />
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[3].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#7FFFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>-->
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <!--<Storyboard>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="Background"
                                                Storyboard.TargetProperty="(Border.Background).                       (SolidColorBrush.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#FF448DCA" />
                                        </ColorAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames BeginTime="0"
                                                 Duration="00:00:00.001"
                                                 Storyboard.TargetProperty="(UIElement.Opacity)"
                                                 Storyboard.TargetName="Highlight">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                          Value="1" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[0].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#F4FFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#EAFFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[2].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#C6FFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                        <ColorAnimationUsingKeyFrames BeginTime="0"
                                                Duration="00:00:00.001"
                                                Storyboard.TargetName="BackgroundGradient"
                                                Storyboard.TargetProperty="(Border.Background).                     (GradientBrush.GradientStops)[3].(GradientStop.Color)">
                                            <SplineColorKeyFrame KeyTime="0"
                                         Value="#6BFFFFFF" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>-->
                                    </VisualState>
                                    <VisualState x:Name="Disabled" />
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates"/>
                                <VisualStateGroup x:Name="ValidationStates"/>
                            </VisualStateManager.VisualStateGroups>
                            <Grid Background="#11FFFFFF"
                FlowDirection="LeftToRight"
                HorizontalAlignment="Center"
                Height="18"
                Margin="0"
                VerticalAlignment="Center"
                Width="19">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="20*" />
                                    <ColumnDefinition Width="20*" />
                                    <ColumnDefinition Width="20*" />
                                    <ColumnDefinition Width="20*" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="23*" />
                                    <RowDefinition Height="19*" />
                                    <RowDefinition Height="19*" />
                                    <RowDefinition Height="19*" />
                                </Grid.RowDefinitions>
                                <Image Grid.ColumnSpan="4" Margin="0" Grid.RowSpan="4" Source="Image\icon_datepicker.png" Stretch="none"/>
                                <!--<Rectangle Grid.ColumnSpan="4"
                       Grid.RowSpan="1"
                       StrokeThickness="1">
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint="0,1"
                                     StartPoint="0,0">
                                        <GradientStop Color="{DynamicResource HeaderTopColor}" />
                                        <GradientStop Color="{DynamicResource ControlMediumColor}"
                                Offset="1" />
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                                <Rectangle.Stroke>
                                    <LinearGradientBrush EndPoint="0.48,-1"
                                     StartPoint="0.48,1.25">
                                        <GradientStop Color="#FF494949" />
                                        <GradientStop Color="#FF9F9F9F"
                                Offset="1" />
                                    </LinearGradientBrush>
                                </Rectangle.Stroke>
                            </Rectangle>-->
                                <!--<Ellipse Grid.ColumnSpan="4"
                     Fill="#FFFFFFFF"
                     HorizontalAlignment="Center"
                     Height="3"
                     StrokeThickness="0"
                     VerticalAlignment="Center"
                     Width="3" d:IsHidden="True" />-->
                            </Grid>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="MyDatePicker" TargetType="{x:Type DatePicker}">

            <Setter Property="Foreground"
          Value="#FF333333" />
            <Setter Property="IsTodayHighlighted"
          Value="True" />
            <Setter Property="SelectedDateFormat"
          Value="Short" />
            <Setter Property="Padding"
          Value="2" />
            <Setter Property="BorderThickness"
          Value="1" />
            <Setter Property="HorizontalContentAlignment"
          Value="Stretch" />
            <!--Set CalendarStyle to DatePickerCalendarStyle.-->
            <Setter Property="CalendarStyle"
          Value="{DynamicResource DatePickerCalendarStyle}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DatePicker}">
                        <Border BorderThickness="1"
                        Padding="{TemplateBinding Padding}" BorderBrush="#5d7fad" Background="White" CornerRadius="5" SnapsToDevicePixels="True" Height="28" x:Name="DatePickerBorder">


                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0"
                                            To="1"
                                            Storyboard.TargetProperty="Opacity"
                                            Storyboard.TargetName="PART_DisabledVisual" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ValidationStates"/>
                            </VisualStateManager.VisualStateGroups>
                            <Grid x:Name="PART_Root"
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalAlignment="Center">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <Button x:Name="PART_Button"
                                Grid.Column="1"
                                Foreground="#0c223a"
                                Focusable="False"
                                HorizontalAlignment="Left"
                                Margin="5,0,5,0"
                                Grid.Row="0"
                                Style="{StaticResource DropDownButtonStyle}"
                                VerticalAlignment="Top" />
                                <TextBox x:Name="PART_MyTextBox"
                                         Grid.Column="0" BorderThickness="0"
                                Foreground="#0c223a" 
                                Focusable="{TemplateBinding Focusable}"
                                HorizontalContentAlignment="Stretch" InputMethod.IsInputMethodEnabled="False"
                                Grid.Row="0"   
                                VerticalContentAlignment="Stretch" FontFamily="Arial" FontSize="12" VerticalAlignment="Center"
                                        >
                                  
                                </TextBox>
                                <DatePickerTextBox x:Name="PART_TextBox"
                                             Visibility="Hidden"      
                                Grid.Column="0"
                                Foreground="#0c223a"
                                Focusable="{TemplateBinding Focusable}"
                                HorizontalContentAlignment="Stretch"
                                Grid.Row="0"
                                VerticalContentAlignment="Stretch" FontFamily="Arial" FontSize="12" VerticalAlignment="Center" Style="{DynamicResource DatePickerTextBoxStyle1}" >
                                    <DatePickerTextBox.Resources>
                                        <Style x:Key="DatePickerTextBoxStyle1" TargetType="{x:Type DatePickerTextBox}">
                                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
                                            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
                                            <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
                                            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
                                            <Setter Property="Template">
                                                <Setter.Value>
                                                    <ControlTemplate TargetType="{x:Type DatePickerTextBox}">
                                                        <Grid>
                                                            <Grid.Resources>
                                                                <SolidColorBrush x:Key="WatermarkBrush" Color="#FFAAAAAA"/>
                                                            </Grid.Resources>
                                                            <VisualStateManager.VisualStateGroups>
                                                                <VisualStateGroup x:Name="CommonStates">
                                                                    <VisualStateGroup.Transitions>
                                                                        <VisualTransition GeneratedDuration="0"/>
                                                                        <VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
                                                                    </VisualStateGroup.Transitions>
                                                                    <VisualState x:Name="Normal"/>
                                                                    <VisualState x:Name="MouseOver">
                                                                        <Storyboard>
                                                                            <ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement"/>
                                                                            <ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="watermark_decorator"/>
                                                                        </Storyboard>
                                                                    </VisualState>
                                                                </VisualStateGroup>
                                                                <VisualStateGroup x:Name="WatermarkStates">
                                                                    <VisualStateGroup.Transitions>
                                                                        <VisualTransition GeneratedDuration="0"/>
                                                                    </VisualStateGroup.Transitions>
                                                                    <VisualState x:Name="Unwatermarked"/>
                                                                    <VisualState x:Name="Watermarked">
                                                                        <Storyboard>
                                                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
                                                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Watermark"/>
                                                                        </Storyboard>
                                                                    </VisualState>
                                                                </VisualStateGroup>
                                                                <VisualStateGroup x:Name="FocusStates">
                                                                    <VisualStateGroup.Transitions>
                                                                        <VisualTransition GeneratedDuration="0"/>
                                                                    </VisualStateGroup.Transitions>
                                                                    <VisualState x:Name="Unfocused"/>
                                                                    <VisualState x:Name="Focused">
                                                                        <Storyboard>
                                                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual"/>
                                                                        </Storyboard>
                                                                    </VisualState>
                                                                </VisualStateGroup>
                                                                <VisualStateGroup x:Name="ValidationStates"/>
                                                            </VisualStateManager.VisualStateGroups>
                                                            <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="1" Padding="{TemplateBinding Padding}">
                                                                <Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                                                    <Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="0"/>
                                                                    <Border x:Name="watermark_decorator" BorderBrush="#FFFFFFFF" BorderThickness="0">
                                                                        <ContentControl x:Name="PART_Watermark" Focusable="False" IsHitTestVisible="False" Opacity="0" Padding="2" Style="{DynamicResource ContentControlStyle1}">
                                                                            <ContentControl.Resources>
                                                                                <Style x:Key="ContentControlStyle1" TargetType="{x:Type ContentControl}">
                                                                                    <Setter Property="Template">
                                                                                        <Setter.Value>
                                                                                            <ControlTemplate TargetType="{x:Type ContentControl}">
                                                                                                <ContentPresenter Visibility="Collapsed"/>
                                                                                            </ControlTemplate>
                                                                                        </Setter.Value>
                                                                                    </Setter>
                                                                                </Style>
                                                                            </ContentControl.Resources>
                                                                        </ContentControl>
                                                                    </Border>
                                                                    <ScrollViewer x:Name="PART_ContentHost" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Template="{DynamicResource ScrollViewerControlTemplate1}">
                                                                        <ScrollViewer.Resources>
                                                                            <ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}">
                                                                                <Grid x:Name="Grid" Background="{TemplateBinding Background}">
                                                                                    <Grid.ColumnDefinitions>
                                                                                        <ColumnDefinition Width="*"/>
                                                                                        <ColumnDefinition Width="Auto"/>
                                                                                    </Grid.ColumnDefinitions>
                                                                                    <Grid.RowDefinitions>
                                                                                        <RowDefinition Height="*"/>
                                                                                        <RowDefinition Height="Auto"/>
                                                                                    </Grid.RowDefinitions>
                                                                                    <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
                                                                                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
                                                                                    <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                                                                    <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                                                                </Grid>
                                                                            </ControlTemplate>
                                                                        </ScrollViewer.Resources>
                                                                    </ScrollViewer>
                                                                    <Border x:Name="FocusVisual" BorderBrush="#FF45D6FA" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
                                                                </Grid>
                                                            </Border>
                                                        </Grid>
                                                    </ControlTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </DatePickerTextBox.Resources>
                                </DatePickerTextBox>
                                <Grid x:Name="PART_DisabledVisual"
                                Grid.ColumnSpan="2"
                                Grid.Column="0"
                                IsHitTestVisible="False"
                                Opacity="0"
                                Grid.Row="0">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*" />
                                        <ColumnDefinition Width="Auto" />
                                    </Grid.ColumnDefinitions>
                                    <Rectangle Grid.Column="0"
                                    Fill="#A5FFFFFF"
                                    RadiusY="3"
                                    Grid.Row="0"
                                    RadiusX="3" />
                                    <Rectangle Grid.Column="1"
                                    Fill="#A5FFFFFF"
                                    Height="18"
                                    Margin="5,0,5,0"
                                    RadiusY="3"
                                    Grid.Row="0"
                                    RadiusX="3"
                                    Width="19" />
                                    <Popup x:Name="PART_Popup"
                                    AllowsTransparency="True"
                                    Placement="Bottom"
                                    PlacementTarget="{Binding ElementName=PART_TextBox}"
                                    StaysOpen="False"  />
                                </Grid>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Validation.HasError" Value="True">

                                <Setter TargetName="DatePickerBorder" Property="BorderBrush" Value="Red"></Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

cs.

View Code
using MCE.Gems.Common.Common;
using MCE.Gems.Common.Events;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace MCE.Gems.Common.Controls.CustomControls
{
    public class CustomDatePicker : DatePicker
    {
        #region Field
       // private static IEventAggregator eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();

        private List<InputMaskChar> _maskChars;

        private static string currentWaterMark;

        private bool isTextChanged;

        private int _caretIndex;

        #endregion

        #region Property
        /// <summary>
        /// Gets the text box in charge of the editable portion of the MyDatePicker.
        /// </summary>
        protected TextBox MyTextBox
        {
            get
            {
                return base.GetTemplateChild("PART_MyTextBox") as TextBox;
            }
        }





        public string WaterMark
        {
            get { return (string)GetValue(WaterMarkProperty); }
            set { SetValue(WaterMarkProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaterMark.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaterMarkProperty =
            DependencyProperty.Register("WaterMark", typeof(string), typeof(CustomDatePicker), new PropertyMetadata(null,new PropertyChangedCallback(OnWaterMarkChanged)));



        public DateTime DefaultCalendarDisplayDate
        {
            get { return (DateTime)GetValue(DefaultCalendarDisplayDateProperty); }
            set { SetValue(DefaultCalendarDisplayDateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DefaultCalendarDisplayDate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DefaultCalendarDisplayDateProperty =
            DependencyProperty.Register("DefaultCalendarDisplayDate", typeof(DateTime), typeof(CustomDatePicker), new PropertyMetadata(null));

        


         /// <summary>
        /// Invoked when the WaterMark dependency property reports a change.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="e"></param>
        private static void OnWaterMarkChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            CustomDatePicker cdp = obj as CustomDatePicker;
            if (cdp.SelectedDate==null&&cdp.MyTextBox!=null)
            {
                cdp.MyTextBox.Text = e.NewValue.ToString();     
            }
            currentWaterMark = e.NewValue.ToString();
        }
        
        #endregion

        static CustomDatePicker()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomDatePicker), new FrameworkPropertyMetadata(typeof(CustomDatePicker)));
           
        }
       
        public CustomDatePicker()
        {
           // eventAggregator.GetEvent<UpdateLanguageEvent>().Subscribe(UpdateMaskLanguage);
            this._maskChars = new List<InputMaskChar>();
                 
        }

      
       

      
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            //load the text box control
            if (this.MyTextBox != null)
            {
                
                this.MyTextBox.GotFocus += new RoutedEventHandler(MyTextBox_GotFocus);
                this.MyTextBox.LostFocus += new RoutedEventHandler(MyTextBox_LostFocus);
                this.MyTextBox.TextChanged += new TextChangedEventHandler(MyTextBox_TextChanged);
                this.MyTextBox.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(MyTextBox_PreviewMouseLeftButtonUp);
                this.MyTextBox.PreviewKeyDown += MyTextBox_PreviewKeyDown;
                this.MyTextBox.PreviewTextInput += MyTextBox_PreviewTextInput;
                this.MyTextBox.SelectionChanged += MyTextBox_SelectionChanged;
                //default
                this.MyTextBox.Text = currentWaterMark;
                this.SelectedDateChanged += CustomDatePicker_SelectedDateChanged;
                this.Loaded += CustomDatePicker_Loaded;
                DataObject.AddPastingHandler(this, new DataObjectPastingEventHandler(MyTextBox_Paste));
                //UpdateInputMask();
            }
            
        }



        void CustomDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            //if (this.IsLoaded)
            //{
                if (this.SelectedDate != null)
                {

                    this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault());
                    UpdateInputMask();
                    this._caretIndex = 10;
                    this.MyTextBox.CaretIndex = 10;

                }
                else
                {
                    this.MyTextBox.Text = WaterMark;
                } 
            //}
           
            //  this.DisplayDate = DateTime.Today;
        }



        void CustomDatePicker_Loaded(object sender, RoutedEventArgs e)
        {

            if (this.SelectedDate != null)
            {
                this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault());
            }
            else
            {
               // this.MyTextBox.Text = WaterMark;
            }
            
        }



        void MyTextBox_SelectionChanged(object sender, RoutedEventArgs e)
        {
            if (!isTextChanged)
            {
                TextBox t = (TextBox)sender;
                this._caretIndex = t.CaretIndex;
            }
            isTextChanged = false;

        }

        /// <summary>
        /// Invokes when a paste event is raised.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyTextBox_Paste(object sender, DataObjectPastingEventArgs e)
        {
            //TODO: play nicely here?
            //

            if (e.DataObject.GetDataPresent(typeof(string)))
            {
                string value = e.DataObject.GetData(typeof(string)).ToString();
                string displayText;

                if (this.ValidateTextInternal(value, out displayText))
                {
                    this.MyTextBox.Text = displayText;
                }
            }

            e.CancelCommand();
        }

        private void MyTextBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (this.SelectedDate == null)
            {
                if (e.ChangedButton == MouseButton.Left && (bool)this.MyTextBox.Tag == true)
                {
                    this.MyTextBox.Select(0, 0);
                }
                this.MyTextBox.Tag = false;

            }


        }

        private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            isTextChanged = true;
            if (string.IsNullOrWhiteSpace(this.MyTextBox.Text))
            {
                this.SelectedDate = null;
               this.MyTextBox.Text = WaterMark;

            }

        }

        private void MyTextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (this.MyTextBox.Text != null)
            {
                try
                {
                    this.SelectedDate = DateTime.Parse(this.MyTextBox.Text);
                    //this.DisplayDate = DateTime.Today;
                }
                catch (Exception)
                {
                    this.SelectedDate = null;
                    this.MyTextBox.Text = WaterMark;
                   // this.MyTextBox.Text = null;

                }
            }
            if (this.DefaultCalendarDisplayDate != null)
            {
              
                this.DisplayDate = this.DefaultCalendarDisplayDate;
            }

            //if (this.SelectedDate != null)
            //{
            //    this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault());
            //}
            //else
            //{
            //    //this.MyTextBox.Text = WaterMark;

            //}


        }

        private void MyTextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            this.MyTextBox.Tag = true;
            if (this.SelectedDate != null)
            {
                this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault());
            }
            else
            {
                UpdateInputMask();
                // this.MyTextBox.Text = "__/__/____";
                this.MyTextBox.Select(0, 0);

            }

        }

        void MyTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {


            //no mask specified, just function as a normal textbox
            if (this._maskChars.Count == 0)
                return;

            if (e.Key == Key.Delete)
            {
                //delete key pressed: delete all text
                this.MyTextBox.Text = this.GetDefaultText();
                this._caretIndex = this.MyTextBox.CaretIndex = 0;
                e.Handled = true;
            }
            else
            {
                //backspace key pressed
                if (e.Key == Key.Back)
                {
                    if (this._caretIndex > 0 || this.MyTextBox.SelectionLength > 0)
                    {
                        if (this.MyTextBox.SelectionLength > 0)
                        {
                            //if one or more characters selected, delete them
                            this.DeleteSelectedText();
                        }
                        else
                        {
                            //if no characters selected, shift the caret back to the previous non-literal char and delete it
                            this.MoveBack();

                            char[] characters = this.MyTextBox.Text.ToCharArray();
                            characters[this._caretIndex] = this._maskChars[this._caretIndex].GetDefaultChar();
                            this.MyTextBox.Text = new string(characters);
                        }

                        //update the base class caret index, and swallow the event
                        this.MyTextBox.CaretIndex = this._caretIndex;
                        e.Handled = true;
                    }
                }
                else if (e.Key == Key.Left)
                {
                    //move back to the previous non-literal character
                    this.MoveBack();
                    e.Handled = true;
                }
                else if (e.Key == Key.Right || e.Key == Key.Space)
                {
                    //move forwards to the next non-literal character
                    this.MoveForward();
                    e.Handled = true;
                }
            }
        }

        void MyTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            if (this._maskChars.Count == 0)
                return;

            this._caretIndex = this.MyTextBox.CaretIndex = this.MyTextBox.SelectionStart;

            if (this._caretIndex == this._maskChars.Count)
            {
                //at the end of the character count defined by the input mask- no more characters allowed
                e.Handled = true;
            }
            else
            {
                //validate the character against its validation scheme
                bool isValid = this.ValidateInputChar(char.Parse(e.Text),
                    this._maskChars[this._caretIndex].ValidationFlags);

                if (isValid)
                {
                    //delete any selected text
                    if (this.MyTextBox.SelectionLength > 0)
                    {
                        this.DeleteSelectedText();
                    }

                    //insert the new character
                    char[] characters = this.MyTextBox.Text.ToCharArray();
                    characters[this._caretIndex] = char.Parse(e.Text);
                    this.MyTextBox.Text = new string(characters);

                    //move the caret on 
                    this.MoveForward();
                }

                e.Handled = true;
            }
        }






        #region validateMethod
        protected virtual bool IsPlaceholderChar(char character, out InputMaskValidationFlags validationFlags)
        {
            validationFlags = InputMaskValidationFlags.None;

            switch (character.ToString().ToUpper())
            {
                case "I":
                    validationFlags = InputMaskValidationFlags.AllowInteger;
                    break;
                case "D":
                    validationFlags = InputMaskValidationFlags.AllowDecimal;
                    break;
                case "A":
                    validationFlags = InputMaskValidationFlags.AllowAlphabet;
                    break;
                case "W":
                    validationFlags = (InputMaskValidationFlags.AllowAlphanumeric);
                    break;
            }

            return (validationFlags != InputMaskValidationFlags.None);
        }
        /// <summary>
        /// Returns a value indicating if the current text value is valid.
        /// </summary>
        /// <returns></returns>
        public virtual bool ValidateTextInternal(string text, out string displayText)
        {
            if (this._maskChars.Count == 0)
            {
                displayText = text;
                return true;
            }

            StringBuilder displayTextBuilder = new StringBuilder(this.GetDefaultText());

            bool valid = (!string.IsNullOrEmpty(text) &&
                text.Length <= this._maskChars.Count);

            if (valid)
            {
                for (int i = 0; i < text.Length; i++)
                {
                    if (!this._maskChars[i].IsLiteral())
                    {
                        if (this.ValidateInputChar(text[i], this._maskChars[i].ValidationFlags))
                        {
                            displayTextBuilder[i] = text[i];
                        }
                        else
                        {
                            valid = false;
                        }
                    }
                }
            }

            displayText = displayTextBuilder.ToString();

            return valid;
        }

        /// <summary>
        /// Validates the specified character against all selected validation schemes.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="validationFlags"></param>
        /// <returns></returns>
        protected virtual bool ValidateInputChar(char input, InputMaskValidationFlags validationFlags)
        {
            bool valid = (validationFlags == InputMaskValidationFlags.None);

            if (!valid)
            {
                Array values = Enum.GetValues(typeof(InputMaskValidationFlags));

                //iterate through the validation schemes
                foreach (object o in values)
                {
                    InputMaskValidationFlags instance = (InputMaskValidationFlags)(int)o;
                    if ((instance & validationFlags) != 0)
                    {
                        if (this.ValidateCharInternal(input, instance))
                        {
                            valid = true;
                            break;
                        }
                    }
                }
            }

            return valid;
        }
        /// <summary>
        /// Validates the specified character against its input mask validation scheme.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="validationType"></param>
        /// <returns></returns>
        private bool ValidateCharInternal(char input, InputMaskValidationFlags validationType)
        {
            bool valid = false;

            switch (validationType)
            {
                case InputMaskValidationFlags.AllowInteger:
                case InputMaskValidationFlags.AllowDecimal:
                    int i;
                    if (validationType == InputMaskValidationFlags.AllowDecimal &&
                        input == '.' && !this.MyTextBox.Text.Contains('.'))
                    {
                        valid = true;
                    }
                    else
                    {
                        valid = int.TryParse(input.ToString(), out i);
                    }
                    break;
                case InputMaskValidationFlags.AllowAlphabet:
                    valid = char.IsLetter(input);
                    break;
                case InputMaskValidationFlags.AllowAlphanumeric:
                    valid = (char.IsLetter(input) || char.IsNumber(input));
                    break;
            }

            return valid;
        }
        #endregion

        #region Method

        public void UpdateInputMask()
        {

            string text = this.MyTextBox.Text;
            this._maskChars.Clear();

            // this.MyTextBox.Text = string.Empty;

            string mask = "ii/ii/iiii";

            //if (string.IsNullOrEmpty(mask))
            //    return;

            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'd', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'd', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)1, DefaultChar = '/', ValidationFlags = InputMaskValidationFlags.None });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'M', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'M', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)1, DefaultChar = '/', ValidationFlags = InputMaskValidationFlags.None });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger });
            this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger });


            //InputMaskValidationFlags validationFlags = InputMaskValidationFlags.None;

            //for (int i = 0; i < mask.Length; i++)
            //{
            //    bool isPlaceholder = this.IsPlaceholderChar(mask[i], out validationFlags);

            //    if (isPlaceholder)
            //    {
            //        this._maskChars.Add(new InputMaskChar(validationFlags));
            //    }
            //    else
            //    {
            //        this._maskChars.Add(new InputMaskChar(mask[i]));
            //    }
            //}

            string displayText;
            if (text.Length > 0 && this.ValidateTextInternal(text, out displayText))
            {
                this.MyTextBox.Text = displayText;
            }
            else
            {
                this.MyTextBox.Text = this.GetDefaultText();
            }
        }



        private  void UpdateMaskLanguage(string obj)
        {
            if (this.SelectedDate == null)
            {
                //this.MyTextBox.Text = WaterMark;
            }
        }

        public string GetDefaultText()
        {
            StringBuilder text = new StringBuilder();
            foreach (InputMaskChar maskChar in this._maskChars)
            {
                text.Append(maskChar.GetDefaultChar());
            }
            return text.ToString();
        }


        /// <summary>
        /// Moves the caret forward to the next non-literal position.
        /// </summary>
        private void MoveForward()
        {
            int pos = this._caretIndex;
            while (pos < this._maskChars.Count)
            {
                if (++pos == this._maskChars.Count || !this._maskChars[pos].IsLiteral())
                {
                    this._caretIndex = this.MyTextBox.CaretIndex = pos;
                    break;
                }
            }
        }

        /// <summary>
        /// Moves the caret backward to the previous non-literal position.
        /// </summary>
        private void MoveBack()
        {
            int pos = this._caretIndex;
            while (pos > 0)
            {
                if (--pos == 0 || !this._maskChars[pos].IsLiteral())
                {
                    this._caretIndex = this.MyTextBox.CaretIndex = pos;
                    break;
                }
            }
        }

        /// <summary>
        /// Deletes the currently selected text.
        /// </summary>
        protected virtual void DeleteSelectedText()
        {
            StringBuilder text = new StringBuilder(this.MyTextBox.Text);
            string defaultText = this.GetDefaultText();
            int selectionStart = this.MyTextBox.SelectionStart;
            int selectionLength = this.MyTextBox.SelectionLength;

            text.Remove(selectionStart, selectionLength);
            text.Insert(selectionStart, defaultText.Substring(selectionStart, selectionLength));
            this.MyTextBox.Text = text.ToString();

            //reset the caret position
            this.MyTextBox.CaretIndex = this._caretIndex = selectionStart;
        }

        #endregion

        [Flags]
        protected enum InputMaskValidationFlags
        {
            None = 0,
            AllowInteger = 1,
            AllowDecimal = 2,
            AllowAlphabet = 4,
            AllowAlphanumeric = 8
        }
        private class InputMaskChar
        {

            private InputMaskValidationFlags _validationFlags;
            private char _literal;
            public char DefaultChar { get; set; }

            public InputMaskChar(InputMaskValidationFlags validationFlags)
            {
                this._validationFlags = validationFlags;
                this._literal = (char)0;
            }

            public InputMaskChar(char literal)
            {
                this._literal = literal;
            }

            public InputMaskChar()
            {

            }

            public InputMaskValidationFlags ValidationFlags
            {
                get { return this._validationFlags; }
                set { this._validationFlags = value; }
            }

            public char Literal
            {
                get { return this._literal; }
                set { this._literal = value; }
            }

            public bool IsLiteral()
            {
                return (this._literal != (char)0);
            }

            public char GetDefaultChar()
            {
                return DefaultChar;
            }

        }

    }


    
}

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/FaDeKongJian/archive/2013/03/20/2972285.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值