kida
kida

Reputation: 159

button click event inside popup in WPF any idea?

am trying to achieve the functionality of Outlook style of Datepicker control.

I have a textbox which am applying a style which looks exactly same as in Outlook but my problem is popup having a calendar and two button as Today and none.As soon as click on Today button the textbox value should set to todays date and if i click None the text box value has to set as none.

The style i have used is

         <Style x:Key="tbCalendarStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <Border BorderThickness="1" BorderBrush="DarkGray">
                        <ScrollViewer x:Name="PART_ContentHost" />
                    </Border>
                    <ToggleButton Template="{StaticResource IconButton}"
                          MaxHeight="21" 
                          Margin="-1,0,0,0" 
                          Name="PopUpImageButton" 
                          Focusable="False"
                          IsChecked="False">
                        <ToggleButton.Content>
                            <Path x:Name="btnArrow4" Margin="4" VerticalAlignment="Center" Width="10" Fill="Black" Stretch="Uniform" HorizontalAlignment="Right" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z "/>
                        </ToggleButton.Content>                        


                    </ToggleButton>
                    <Popup IsOpen="{Binding Path=IsChecked, ElementName=PopUpImageButton, Mode=TwoWay}" x:Name="CustomPopup" Margin="0,-1,0,0" PopupAnimation="Fade" StaysOpen="False">

                        <StackPanel Orientation="Vertical" removed="BlueViolet">
                            <Grid >
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="164"/>
                                    <RowDefinition Height="10"/>
                                </Grid.RowDefinitions>
                                <Calendar Grid.Row="0" Margin="0,-1,0,0" x:Name="CalDisplay"
                                  SelectedDate="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Text, Mode=TwoWay, Converter={StaticResource calendarConverter}}" 
                                  Focusable="False" 
                                  DisplayDate="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Text, Mode=OneWay, Converter={StaticResource calendarConverter}}"    
                                  >
                                    <Control.Triggers>
                                        <EventTrigger RoutedEvent="Calendar.SelectedDatesChanged">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <BooleanAnimationUsingKeyFrames Storyboard.TargetName="PopUpImageButton" Storyboard.TargetProperty="IsChecked">
                                                        <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"></DiscreteBooleanKeyFrame>
                                                    </BooleanAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>
                                    </Control.Triggers>
                                </Calendar>
                            </Grid>
                            <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight">
                                <Button Content="Today" Grid.Row="1" Width="50" VerticalAlignment="Center" Margin="20 0 0 10" Name="btnToday">
                                    <Button.Triggers>
                                        <EventTrigger RoutedEvent="Button.Click">
                                            // what should i do to achieve the above logic
                                        </EventTrigger>
                                    </Button.Triggers>
                                </Button>

                                <Button Content="None" Grid.Row="1" Margin="30 0 0 10" Width="50" VerticalAlignment="Center" Name="btnNone">
                                    <Button.Triggers>
                                        <EventTrigger RoutedEvent="Button.Click">

                                        </EventTrigger>
                                    </Button.Triggers>
                                </Button>
                            </StackPanel>
                        </StackPanel>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Visibility" TargetName="PopUpImageButton" Value="Visible" />
                    </Trigger>
                    <Trigger Property="IsFocused" Value="true">
                        <Setter Property="Visibility" TargetName="PopUpImageButton" Value="Visible" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    </Style>

Any help or idea to achieve this would be highly appreciated.

Upvotes: 0

Views: 2448

Answers (2)

Sheridan
Sheridan

Reputation: 69959

The general way to attach event handlers to elements that are defined within a ControlTemplate is to override the FrameworkElement.OnApplyTemplate method:

public override void OnApplyTemplate()
{
    Button button = (Button)Template.FindName("btnToday", this);
    button.Click += SomeClickHandler;
}

UPDATE >>>

Where I have used this (as the second input parameter) above, it stands for the templatedParent input parameter. The correct value will depend on which object the Template was applied to... in this case, I believe that it should be the this object.

UPDATE 2 >>>

Sorry, I thought that you could write a Click event handler. Here is one:

private void SomeClickHandler(object sender, RoutedEventArgs e)
{
    // Set your DateTime here
}

Upvotes: 0

dev hedgehog
dev hedgehog

Reputation: 8791

If you have a custom control then I suggest you to override the method OnApplyTemplate and use GetTemplatedChild to find the Button, subscribe to its click and thats it except you will have to find the TextBox and set its Text inside the handler.

If you cannot do so for whatever reason here is a small trick how to make it still work

Take a look at this:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    x:Class="WPFControls.Generic"
                    xmlns:local="clr-namespace:WPFControls">

<Style TargetType="{x:Type local:MyChildControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyChildControl}">
                <Border Background="{TemplateBinding Background}"
                        SnapsToDevicePixels="True">
                    <StackPanel>
                        <TextBox x:Name="tbx1"/>
                        <Button Content="{TemplateBinding Content}" Click="OnClick"/>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
....

And this is the code behind for Generic.xaml dictionary.

public partial class Generic
{
    public void OnClick(object sender, RoutedEventArgs e)
    {
        MyChildControl control = FindAncestor<MyChildControl>((DependencyObject)sender);
        TextBox tbx = control.Template.FindName("tbx1", control) as TextBox;
        tbx.Text = "It works!";
    }

    public static T FindAncestor<T>(DependencyObject current) where T : DependencyObject
    {
        current = VisualTreeHelper.GetParent(current);

        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }

            current = VisualTreeHelper.GetParent(current);
        };

        return null;
    }
}

This is mine MainWindow.xaml:

<Window ....>
    <Grid>
        <local:MyChildControl Content="Click me!"/>
    </Grid>
</Window>

Upvotes: 1

Related Questions