You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF自定义DatePicker:更换图标及文本框点击弹出日历问题

解决方案

1. 替换图标为FontAwesome CalendarAltSolid & 修复图标截断

首先更新后台代码,取消隐藏PART_Button并绑定自定义模板:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Client.customcontrols
{
    public class CustomDatePicker : DatePicker
    {
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            if (Template.FindName("PART_TextBox", this) is TextBox textbox)
            {
                textbox.IsReadOnly = true;
                textbox.Cursor = Cursors.Hand;
                textbox.PreviewMouseLeftButtonDown += Textbox_PreviewMouseLeftButtonDown;
            }
            
            if (Template.FindName("PART_Button", this) is Button button)
            {
                button.Visibility = Visibility.Visible;
                // 应用自定义模板
                if (TryFindResource("ButtonTemplate") is ControlTemplate template)
                {
                    button.Template = template;
                }
            }
        }

        private void Textbox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IsDropDownOpen = true;
            e.Handled = true; // 阻止默认行为导致弹窗关闭
        }
    }
}

然后修改XAML中的按钮模板,解决截断问题:

<customcontrols:CustomDatePicker x:Name="DataCreazione"
                                 SelectedDate="{Binding DataCreazione, StringFormat={}{0:dd/MM/yyyy}}"
                                 controls:TextBoxHelper.Watermark="Data Creazione"
                                 Cursor="Hand"
                                 SelectedDateFormat="Short"
                                 VerticalAlignment="Top"
                                 HorizontalAlignment="Left"
                                 Margin="20,10,0,0"
                                 Grid.ColumnSpan="3"
                                 Grid.Row="1">
    <customcontrols:CustomDatePicker.Resources>
        <ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
            <!-- 移除固定宽度,添加内边距避免截断 -->
            <Grid HorizontalAlignment="Right" Padding="8,0">
                <iconPacks:PackIconControl Kind="{x:Static iconPacks:PackIconFontAwesomeKind.CalendarAltSolid}"
                                           Width="16" Height="16"
                                           Foreground="#81b3d4"
                                           HorizontalAlignment="Center"
                                           VerticalAlignment="Center"
                                           Margin="0,0,8,0"/>
            </Grid>
            <!-- 可选:添加鼠标悬停效果 -->
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="#5a9fc7"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </customcontrols:CustomDatePicker.Resources>
</customcontrols:CustomDatePicker>

2. 修复点击文本框弹窗消失问题

在文本框的PreviewMouseLeftButtonDown事件中添加e.Handled = true,这会阻止DatePicker的默认鼠标事件逻辑覆盖弹窗状态,确保弹窗保持打开直到用户选择日期或点击外部区域。

3. 图标截断问题说明

原来的模板中Grid设置了固定Width="40",且图标左对齐,导致图标边缘被控件容器截断。移除固定宽度并添加Padding="8,0",同时让图标居中显示,就能给图标左侧留出足够空间,解决截断问题。

内容的提问来源于stack exchange,提问作者markzzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:05:31