Mirek
Mirek

Reputation: 71

Click event is not raised for Button in popup on datagrid

I'am quite new with WPF and still trying to figure it out in all its details ;) I have a strange issue with the button not raising its click event. I have a UserControl called PopupButton which is basically a button with a popup showed on click. The content of the popup is ContentPresenter and is binded to the dependency property called PopupContentHolder on the PopupButton. Then on the main form I have a DataGrid with DataGridTemplateColumn where in the <DataGridTemplateColumn.CellTemplate> <DataTemplate> I placed my PopupButton. Then I assign a list box with an ItemTemplate as the content of the popup for my PopupButton. In simple this looks as follows

<DataGrid HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        HorizontalContentAlignment="Stretch"
        ColumnHeaderHeight="40"
        FontSize="11"
        HorizontalScrollBarVisibility="Disabled"
        ItemsSource="{Binding Pocos}"
        RowHeight="30"
        SnapsToDevicePixels="True"
        VerticalScrollBarVisibility="Disabled">
<DataGrid.Columns>
    <DataGridTemplateColumn MinWidth="70" Header="NAme">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <controls:PopupButton DoPopupOnMainButton="True"
                                        Foreground="{StaticResource HeaderLinkActiveColor}"
                                        MarkButtonOnPopup="True"
                                        PopupBackground="{StaticResource PopupBackground}"
                                        PopupPadding="5"
                                        ShowDownArrow="False"
                                        Text="Some test button">
                    <controls:PopupButton.PopupContentHolder>
                        <StackPanel>
                            <ListBox Background="Transparent" ItemsSource="{Binding Tenders}">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <Button Margin="0,2,0,0"
                                                Click="Button_Click"
                                                Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},
                                                                    Path=DataContext.SaveCommand}"
                                                Content="{Binding .}"
                                                FontSize="11" />
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </StackPanel>
                    </controls:PopupButton.PopupContentHolder>
                </controls:PopupButton>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

Now the problem is with the button inside the ListBox in PopupButton, Neither Click event nor Command is raised. Moreover when I put the PopupButton outside the DataGrid then everythinkg works perfect. Also when I put above list box directly in grid cell then it works. Maybe its something wrong with my PopupButtonControl.

<UserControl x:Class="WpfApplication1.PopupButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         x:Name="userControlRoot"
         Width="Auto"
         Height="Auto">
<UserControl.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis" />

    <Storyboard x:Key="PopupCloseStoryBoard">
        <BooleanAnimationUsingKeyFrames Storyboard.TargetName="popup" Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0.1" Value="False" />
        </BooleanAnimationUsingKeyFrames>
    </Storyboard>

    <Storyboard x:Key="PopupOpenStoryBoard">
        <BooleanAnimationUsingKeyFrames Storyboard.TargetName="popup" Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0.0" Value="True" />
        </BooleanAnimationUsingKeyFrames>
    </Storyboard>


</UserControl.Resources>

<Grid>

    <Border x:Name="brdButtonBack"
            Background="Transparent"
            CornerRadius="3,3,0,0"
            Padding="{Binding Padding,
                              ElementName=userControlRoot}" />

    <Button x:Name="btnMain"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Click="btn_Click"
            Command="{Binding MainCommand,
                              ElementName=userControlRoot}"
            Content="{Binding Text,
                              ElementName=userControlRoot}"
            IsEnabled="{Binding IsEnabled,
                                ElementName=userControlRoot}" />

    <Popup x:Name="popup"
           MinWidth="{Binding ActualWidth,
                              ElementName=userControlRoot}"
           AllowsTransparency="True"
           Placement="Bottom"
           PlacementTarget="{Binding ElementName=brdButtonBack}"
           PopupAnimation="Slide"
           StaysOpen="False">
        <Border Background="{Binding PopupBackground,
                                     ElementName=userControlRoot}"
                BorderBrush="White"
                CornerRadius="0,3,3,3"
                Padding="{Binding PopupPadding,
                                  ElementName=userControlRoot}">

            <ContentPresenter Content="{Binding PopupContentHolder, ElementName=userControlRoot}" />
        </Border>
    </Popup>

</Grid>

I have simplified the control but the problem reproduces with that version too. The code behind for the control mostly contains dependency properties, the only logic is shown below

public partial class PopupButton : UserControl
{
    //... dependency properties

    public PopupButton()
    {
        InitializeComponent();
    }

    private void btn_Click(object sender, RoutedEventArgs e)
    {
            Storyboard s = (Storyboard)TryFindResource("PopupOpenStoryBoard");
            s.Begin();
    }

    private void popup_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        //trick to close popup when the button inside is clicked
        //this must be done with storyboard and delay
        //since popup can not be closed before the event reaches clicked
        //button
        if (e.Source is Button)
        {
            Storyboard s = (Storyboard)TryFindResource("PopupCloseStoryBoard");
            s.Begin();
        }
    }
}

Has anyone any clue what can be wrong with it? Thanks.

Upvotes: 3

Views: 1288

Answers (2)

Mirek
Mirek

Reputation: 71

I did finally solve this by rewriting PopupButton as CustomControl. There, instead of firing StoryBoard to close the popup, when the contained button is clicked I used following code

mainPopup.AddHandler(Button.ClickEvent, new RoutedEventHandler(mainPopup_ButtonClick), true);

Adding a button click handler for main popup, which will be called on the popup even if the event is already handled by the source button.

    void mainPopup_ButtonClick(object sender, RoutedEventArgs e)
    {
        MainPopup.IsOpen = false;
    }

More info about handling already handled routed events here

Upvotes: 1

seveves
seveves

Reputation: 1282

Maybe it is just a typo because there is a btn_Click and Button_Click event handler in your code. Would you mind providing the code of the PopupContentHolder or maybe the whole PopupButton class?

Upvotes: 0

Related Questions