【问题标题】:Toggle datepicker calendar when clicking/touching PART_Textbox单击/触摸 PART_Textbox 时切换日期选择器日历
【发布时间】:2014-01-06 12:01:51
【问题描述】:

我正在用 xaml 编写日期选择器样式 日历弹出窗口由日期选择器文本框旁边的日历按钮切换 我希望在单击/触摸文本框时也切换日历

当向 datepicker 样式添加事件触发器时,日历会在触摸文本框时切换,但仅在鼠标单击时显示并保持打开状态,当单击/触摸 datepicker 日历按钮时,日历会立即打开和关闭。

<EventTrigger RoutedEvent="TextBox.PreviewMouseDown">
<EventTrigger.Actions>
    <BeginStoryboard x:Name="myBeginStoryboard">
        <Storyboard x:Name="myStoryboard">
            <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsDropDownOpen">
                <DiscreteBooleanKeyFrame KeyTime="00:00:00"
                                         Value="True" />
            </BooleanAnimationUsingKeyFrames>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>

我的问题:

  • 有没有比使用事件触发器更好的方法来实现所需的行为?
  • 当事件触发器只设置日历可见时,如何在触摸控件时显示和隐藏日历?
  • 是否可以在 xaml 中将反转的“IsDropDownOpen”值分配给此属性?
  • 或者是否可以在 xaml 中使用条件语句(如果?)来处理隐藏和显示?

【问题讨论】:

  • 在您的情况下,您需要决定隐藏日历的事件(动作),可能是双击?我尝试了事件GotFocusLostFocus,但没有帮助。简要回答您的问题(这是我的看法):1 - 更好,正在寻找某人。我认为您可以应用附加的行为,但也必须通过操作确定关闭日历; 2 - 取决于动作,关闭日历; 3 - 不,但您可以设置反转的时间,4 - 不。

标签: wpf xaml datepicker


【解决方案1】:

忘记EventTrigger,因为它没有给你足够的控制权。而不是使用它,只需将bool IsDropDownOpen 属性添加到您的视图模型或代码中并将其绑定到DatePicker.IsDropDownOpen 属性。这样,您就可以在任何时候随意打开和关闭Popup 和/或响应任何单个事件或事件集合。例如:

public void TextBoxPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    IsDropDownOpen = true;
}

private void TextBoxPreviewTouchDown(object sender, TouchEventArgs e)
{
    IsDropDownOpen = true;
}

private void DatePickerSelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
    IsDropDownOpen = false;
}

【讨论】:

  • +1:我脑子里飞出来的事件DataPicker.SelectionChanged,加上你的答案适合MVVM模式。
【解决方案2】:

认为您使用了错误的事件。您需要深入了解 DatePicker 中的 PART_TextBox 事件 PreviewMouseLeftButtonUp。下面的代码为您的 DatePicker 命名 Date 您需要为您需要的任何其他事件添加此逻辑。

NB 如果使用 MVVM 实践处理,这也会更优雅

    private void PART_TextBox_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        if (Date.IsDropDownOpen)
            Date.IsDropDownOpen = false;
        else
            Date.IsDropDownOpen = true;
    }

【讨论】:

    【解决方案3】:

    使用 Blend 制作控件模板,“DatePickerControlTemplate1”作为日期选择器,然后找到 x:Name="PART_TextBox"。您可以在 MouseEnter 和 MouseLeftButtonDown 上使用 EventTriggers 或在 LeftClick 上使用 InputBinding

                    <DatePickerTextBox x:Name="PART_TextBox" Grid.Column="0" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="Stretch" Grid.Row="0" VerticalContentAlignment="Stretch" Style="{StaticResource BlueTextBoxStyle}">
                        <TextBox.InputBindings>
                            <MouseBinding Gesture="LeftClick" Command="{Binding ShowCalendarCommand}" />
                        </TextBox.InputBindings>
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseEnter">
                                <cmd:EventToCommand Command="{Binding ShowCalendarCommand}" PassEventArgsToCommand="True" />
                            </i:EventTrigger>
                            <i:EventTrigger EventName="MouseLeftButtonDown">
                                <cmd:EventToCommand Command="{Binding ShowCalendarCommand}" PassEventArgsToCommand="True" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                     </DatePickerTextBox>
    

    MVVM XAML:

        <DatePicker IsDropDownOpen="{Binding ShowCalendar}" Template="{StaticResource DatePickerControlTemplate1}"/>
    

    视图模型:

        private bool _showCalendar = false;
        public bool ShowCalendar
        {
            get
            {
                return _showCalendar;
            }
            set
            {
                if (_showCalendar != value)
                {
                    _showCalendar = value;
                    RaisePropertyChanged(() => ShowCalendar);
                }
            }
        }
    
        public RelayCommand ShowCalendarCommand { get; private set; }
    
        ShowCalendarCommand = new RelayCommand(ExecuteShowCalendarCommand);
    
        private void ExecuteShowCalendarCommand()
        {
            ShowCalendar = true;
        }
    

    不幸的是,由于日历没有焦点,除非您在弹出窗口的 DatePicker 控件模板中设置 StaysOpen="true",否则它将关闭

    “PART_Popup”:

        <Popup x:Name="PART_Popup" AllowsTransparency="True" Placement="Bottom" StaysOpen="true" />                 
    

    【讨论】:

      猜你喜欢
      • 2014-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多