Search code examples
c#wpftemplatesdatepickermahapps.metro

Custom DatePicker: how can I change icon image and open the popup clicking on TextBox on codebehind?


Here's my Custom DatePicker:

<customcontrols:CustomDatePicker x:Name="DataCreazione"
                                 SelectedDate="{Binding DataCreazione, StringFormat={}{0:dd/MM/yyyy}}"
                                 controls:TextBoxHelper.Watermark="Data Creazione"
                                 Cursor="Hand"
                                 BorderThickness="0"
                                 SelectedDateFormat="Short"
                                 Margin="0,0,0,0"
                                 Grid.ColumnSpan="3"
                                 Grid.Row="1" />

Which I apply this template on code behind:

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 += PreviewMouseLeftButtonDown_Click;
            }
            if (Template.FindName("PART_Button", this) is Button button)
            {
                button.Visibility = Visibility.Hidden;
            }
        }

        private void PreviewMouseLeftButtonDown_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            IsDropDownOpen = true;
        }
    }
}

I'd like to:

  1. instead of hide the icon, I'd like to change the image of it (using PackIconFontAwesome's CalendarAltSolid), size 16x16, Margin 0,0,8,0
  2. once I click on the textbox, have the same behaviour on clicking on the icon (popup opened, which stay open until I select a date); instead, with PreviewMouseLeftButtonDown, it seem it keep popup open until I press left mouse click, once its "up" the popup vanish

Can you help me on this?

EDIT: after mm8 answer, I get the icon "cutted" on the left:

enter image description here

Here's the actual markup:

<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 Width="40"
                  Margin="0,0,0,0"
                  HorizontalAlignment="Right">
                <iconPacks:PackIconControl Kind="{x:Static iconPacks:PackIconFontAwesomeKind.CalendarAltSolid}"
                                           Width="16"
                                           Height="16"
                                           Foreground="#81b3d4"
                                           HorizontalAlignment="Right"
                                           VerticalAlignment="Center"
                                           Margin="0,0,10,0" />
            </Grid>
        </ControlTemplate>
    </customcontrols:CustomDatePicker.Resources>
</customcontrols:CustomDatePicker>

Solution

  • You can always define custom template for the Button, e.g.:

    <customcontrols:CustomDatePicker x:Name="DataCreazione"
                                     SelectedDate="{Binding DataCreazione, StringFormat={}{0:dd/MM/yyyy}}"
                                     controls:TextBoxHelper.Watermark="Data Creazione"
                                     Cursor="Hand"
                                     BorderThickness="0"
                                     SelectedDateFormat="Short"
                                     Margin="0,0,0,0"
                                     Grid.ColumnSpan="3"
                                     Grid.Row="1">
        <customcontrols:CustomDatePicker.Resources>
            <ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
                <Grid Background="White">
                    <iconPacks:PackIconControl Kind="{x:Static iconPacks:PackIconFontAwesomeKind.CalendarAltSolid}"
                                               Width="16"
                                               Height="16"
                                               Foreground="#81b3d4"
                                               VerticalAlignment="Center" />
                </Grid>
            </ControlTemplate>
        </customcontrols:CustomDatePicker.Resources>
    </customcontrols:CustomDatePicker>
    

    if (Template.FindName("PART_Button", this) is Button button)
    {
        button.Template = FindResource("ButtonTemplate") as ControlTemplate;
    }
    

    As for your other requirement, I think it should work if you handle the MouseLeftButtonUp event and set the Focusable property of the control to false:

    if (Template.FindName("PART_TextBox", this) is TextBox textbox)
    {
        textbox.IsReadOnly = true;
        textbox.Cursor = Cursors.Hand;
    
        Focusable = false;
        textbox.MouseLeftButtonUp += (e, s) => IsDropDownOpen = true;
    }