【问题标题】:WPF DatePicker make separator fixed and always visibleWPF DatePicker 使分隔符固定并始终可见
【发布时间】:2017-05-02 19:41:10
【问题描述】:

我正在开发一个 WPF 应用程序,我想在其中使用默认的 DatePicker 控件。我也想让用户手动插入日期,但我想防止分隔符(“/”)被用户删除。 (更准确地说,即使 DatePicker 的文本框是“空的”,分隔符应该仍然存在)

可以在不创建新的自定义控件的情况下完成此操作吗?谢谢!

【问题讨论】:

    标签: wpf datepicker


    【解决方案1】:

    我做了以下示例:

    <DatePicker HorizontalAlignment="Left" Margin="132,118,0,0" VerticalAlignment="Top" Width="204" Name="DatePicker"
                        SelectedDateChanged="DatePicker_OnSelectedDateChanged">
                <DatePicker.Resources>
                    <Style TargetType="{x:Type DatePickerTextBox}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Grid>
    
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                        </Grid.ColumnDefinitions>
    
                                        <TextBox x:Name="TextBox1" Grid.Column="0" 
                                                 Style="{StaticResource DatePickerTextBoxStyle}"
                                                 TextChanged="OnTextboxTextChanged1" PreviewTextInput="OnPreviewTextInput1"/>
                                        <Label Grid.Column="1" Content="/" FontSize="18" HorizontalAlignment="Center"/>
                                        <TextBox x:Name="TextBox2" Grid.Column="2" Style="{StaticResource DatePickerTextBoxStyle}"
                                                 TextChanged="OnTextboxTextChanged2" PreviewTextInput="OnPreviewTextInput2"/>
                                        <Label Grid.Column="3" Content="/" FontSize="18" HorizontalAlignment="Center"/>
                                        <TextBox x:Name="TextBox3" Grid.Column="4" Style="{StaticResource DatePickerTextBoxStyle}"
                                                 TextChanged="OnTextboxTextChanged3" PreviewTextInput="OnPreviewTextInput3"/>
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DatePicker.Resources>
            </DatePicker>
    

    在你的代码隐藏中:

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private static void TrimText(TextBox textbox)
            {
                textbox.Text = textbox.Text.Trim();
                if (textbox.Text.Length == 2) textbox.Text = textbox.Text.PadLeft(2, '0');
                textbox.CaretIndex = textbox.Text.Length;
            }
    
            private void OnTextboxTextChanged1(object sender, TextChangedEventArgs e)
            {
                var textbox = sender as TextBox;
                if (textbox == null) return;
                TrimText(textbox);
                if (textbox.Text.Length != 2) return;
                var datePickerTxtBox = DatePicker.Template.FindName("PART_TextBox", DatePicker) as DatePickerTextBox;
                var secondTxtbox = datePickerTxtBox.Template.FindName("TextBox2", datePickerTxtBox) as TextBox;
                secondTxtbox.Focus();
            }
    
            private void OnTextboxTextChanged2(object sender, TextChangedEventArgs e)
            {
                var textbox = sender as TextBox;
                if (textbox == null) return;
                TrimText(textbox);
                if (textbox.Text.Length != 2) return;
                var datePickerTxtBox = DatePicker.Template.FindName("PART_TextBox", DatePicker) as DatePickerTextBox;
                var thirdTxtbox = datePickerTxtBox.Template.FindName("TextBox3", datePickerTxtBox) as TextBox;
                thirdTxtbox.Focus();
            }
    
            private void OnTextboxTextChanged3(object sender, TextChangedEventArgs e)
            {
                var textbox = sender as TextBox;
                if (textbox == null) return;
                TrimText(textbox);
                if (textbox.Text.Length != 2) return;
                var datePickerTxtBox = DatePicker.Template.FindName("PART_TextBox", DatePicker) as DatePickerTextBox;
                var firstTxtbox = datePickerTxtBox.Template.FindName("TextBox1", datePickerTxtBox) as TextBox;
                var secondTxtbox = datePickerTxtBox.Template.FindName("TextBox2", datePickerTxtBox) as TextBox;
                DateTime date;
                var text = firstTxtbox.Text + secondTxtbox.Text + textbox.Text;
                if (!DateTime.TryParseExact(text,"ddMMyy",null,DateTimeStyles.None, out date))
                    firstTxtbox.Text = secondTxtbox.Text = textbox.Text = string.Empty;
                else DatePicker.DisplayDate = date;
            }
    
            private void OnPreviewTextInput1(object sender, TextCompositionEventArgs e)
            {
                e.Handled = !(new Regex("[0-9]+").IsMatch(e.Text));
            }
    
            private void OnPreviewTextInput2(object sender, TextCompositionEventArgs e)
            {
                e.Handled = !(new Regex("[0-9]+").IsMatch(e.Text));
    
            }
    
            private void OnPreviewTextInput3(object sender, TextCompositionEventArgs e)
            {
                e.Handled = !(new Regex("[0-9]+").IsMatch(e.Text));
            }
    
            private void DatePicker_OnSelectedDateChanged(object sender, SelectionChangedEventArgs e)
            {
                var newDate = DateTime.Parse(e.Source.ToString());
                DatePicker.DisplayDate = newDate;
                var datePickerTxtBox = DatePicker.Template.FindName("PART_TextBox", DatePicker) as DatePickerTextBox;
                var firstTxtbox = datePickerTxtBox.Template.FindName("TextBox1", datePickerTxtBox) as TextBox;
                var secondTxtbox = datePickerTxtBox.Template.FindName("TextBox2", datePickerTxtBox) as TextBox;
                var thirdTxtbox = datePickerTxtBox.Template.FindName("TextBox3", datePickerTxtBox) as TextBox;
                firstTxtbox.Text = DatePicker.DisplayDate.ToString("dd");
                secondTxtbox.Text = DatePicker.DisplayDate.ToString("MM");
                thirdTxtbox.Text = DatePicker.DisplayDate.ToString("yy");
            }
        }
    

    这只是您如何解决此问题的一个示例。它缺乏一些验证,主要是在用于保存年、月和日值的内部文本框中。然而,它是你可能想要的东西

    编辑>>> 因为我有很多重复的代码,所以必须改进代码隐藏以用于生产。但这只是一个例子。

    EDIT2>>>> 看起来是这样的:

    【讨论】:

    • 不幸的是,经典库不提供执行此操作的选项,而且我确信我不是唯一一个想要使用具有固定分隔符的 DatePicker 的人。另一方面,感谢您的回复。实现我想要的行为对我很有用。 :)
    猜你喜欢
    • 2011-05-10
    • 2012-09-03
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多