0

DatePicker クラスを派生させて、ユーザーが DateMode (日、月、年) に従ってのみコントロールを使用できるようにする追加の DateMode プロパティをサポートしました。そのため、DateMode が Year に設定されている場合、コントロールはそれ以上ドリルダウンして月を表示したり、月の日を表示したりすることはできません。コントロールはうまく機能していますが、1 つの問題があります。DatePicker テンプレートから 'PART_TextBox' コントロールに文字列の書式設定を適用しましたが、DateMode に基づいて書式設定が変更されますが、DatePicker コントロールがフォーカスを失うとすぐに書式設定が失われます。以下は、派生した DatePicker 制御コードです。

public class MyDatePicker : DatePicker
{
    public string DateMode
    {
        get { return (string)GetValue(DateModeProperty); }
        set { SetValue(DateModeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for DateMode.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DateModeProperty =
        DependencyProperty.Register("DateMode", typeof(string), typeof(MyDatePicker), new UIPropertyMetadata("Day"));

    protected override void OnCalendarOpened(RoutedEventArgs e)
    {
        var popup = this.Template.FindName("PART_Popup", this) as Popup;
        var tb = this.Template.FindName("PART_TextBox", this) as TextBox;

        if (popup != null && popup.Child is System.Windows.Controls.Calendar)
        {
            if (DateMode == "Year")
                ((System.Windows.Controls.Calendar)popup.Child).DisplayMode = CalendarMode.Decade;
            else if (DateMode == "Month")
                ((System.Windows.Controls.Calendar)popup.Child).DisplayMode = CalendarMode.Year;
            else if (DateMode == "Day")
                ((System.Windows.Controls.Calendar)popup.Child).DisplayMode = CalendarMode.Month;
        }
        ((System.Windows.Controls.Calendar)popup.Child).DisplayModeChanged += new EventHandler<CalendarModeChangedEventArgs>(DatePickerCo_DisplayModeChanged);
    }

    protected override void OnCalendarClosed(RoutedEventArgs e)
    {
        base.OnCalendarClosed(e);
        IsDropDownOpen = false;
        var popup = this.Template.FindName("PART_Popup", this) as Popup;
        ((System.Windows.Controls.Calendar)popup.Child).DisplayModeChanged -= new EventHandler<CalendarModeChangedEventArgs>(DatePickerCo_DisplayModeChanged);
    }

    private void DatePickerCo_DisplayModeChanged(object sender, CalendarModeChangedEventArgs e)
    {
        var popup = this.Template.FindName("PART_Popup", this) as Popup;
        var tb = this.Template.FindName("PART_TextBox", this) as TextBox;

        if (popup != null && popup.Child is System.Windows.Controls.Calendar)
        {
            var _calendar = popup.Child as System.Windows.Controls.Calendar;

            if (DateMode == "Month" && _calendar.DisplayMode == CalendarMode.Month)
            {
                if (IsDropDownOpen)
                {
                    this.SelectedDate = _calendar.DisplayDate;
                    this.IsDropDownOpen = false;
                    _calendar.DisplayMode = CalendarMode.Year;
                }
                tb.Text = this.SelectedDate.Value.ToString("MMM yyyy");
            }
            else if (DateMode == "Year" && _calendar.DisplayMode == CalendarMode.Year)
            {
                if (IsDropDownOpen)
                {
                    this.SelectedDate = _calendar.DisplayDate;
                    this.IsDropDownOpen = false;
                    _calendar.DisplayMode = CalendarMode.Decade;
                }
                tb.Text = this.SelectedDate.Value.ToString("yyyy");
            }
        }
    }
 }
4

1 に答える 1

0

おそらく基本クラスに干渉していると思います。正確な設定はわかりませんがPART_TextBox、によって設定された Binding があり、DatePickerおそらく LostFocus で更新され、ループバックしてText直接設定した値をクリアしていると思います。BindingOperations.GetBindingを使用してバインディングにアクセスし、直接Text設定する代わりにその StringFormat を変更してみてください。Text

于 2013-02-07T21:11:47.467 に答える