Search code examples
c#wpfstoryboarddatatemplateitemscontrol

Storyboard in DataTemplate refer to extern control


Need to make a reaction. When you press the button on the ItemsControl that Popup hide. I did a layout, assuming that should work, but does not work, please help.

<Style x:Key="gbListViewItemStyle"
         TargetType='{x:Type ListViewItem}' BasedOn='{StaticResource BaseListBoxItemStyle}'>
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid>
                            <ToggleButton x:Name="pupMenuButton" Command="{Binding Path=ActionCommand}" Style="{DynamicResource FlatToggleButtonStyle}">
                                <Grid>
                                    <TextBlock>text</TextBlock>
                                </Grid>
                            </ToggleButton>
                            <Popup Placement="Bottom" AllowsTransparency="True" StaysOpen="False"
                               PopupAnimation="Fade" x:Name="pupMenu" 
                                   IsOpen="{Binding ElementName=pupMenuButton, Path=IsChecked}">
                                <ItemsControl ItemsSource="{Binding Path=ListItems}" >
                                    <ItemsControl.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <StackPanel/>
                                        </ItemsPanelTemplate>
                                    </ItemsControl.ItemsPanel>
                                    <ItemsControl.ItemTemplate>
                                        <DataTemplate>
                                            <Button Content="{Binding Text1}" Command="{Binding Path=ActionCommand}" CommandParameter="{Binding}" Style="{DynamicResource ButtonStyleFlatBorder}">
                                                <Button.Triggers>
                                                    <EventTrigger RoutedEvent="ButtonBase.Click">
                                                        <BeginStoryboard>
                                                            <Storyboard>
                                                                <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(ToggleButton.IsChecked)" Storyboard.TargetName="pupMenuButton">
                                                                    <DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
                                                                </BooleanAnimationUsingKeyFrames>
                                                            </Storyboard>
                                                        </BeginStoryboard>
                                                    </EventTrigger>
                                                </Button.Triggers>
                                            </Button>
                                        </DataTemplate>
                                    </ItemsControl.ItemTemplate>
                                </ItemsControl>
                            </Popup>
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Returned error: "Can not find the name "pupMenuButton" in the namespace "System.Windows.Controls.Button"." Here Storyboard does not work, why? How to make work?


Solution

  • In xaml, there is the concept of namescopes http://msdn.microsoft.com/en-us/library/ms746659.aspx. Named elements within one namescope do not know about elements in another namescope. In this case the DataTemplate for ItemTemplate property is it's own namescope so binding to element name pupMenuButton will not work. You could listen for the click event at the grid level since the grid is in the same namescope as your pupMenuButton ToggleButton. That would behave the same since each button created by the datatemplate would raise bubbling click events that would eventually reach the grid.

    <Style x:Key="gbListViewItemStyle"
         TargetType='{x:Type ListViewItem}' BasedOn='{StaticResource BaseListBoxItemStyle}'>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <Grid.Triggers>
                        <EventTrigger RoutedEvent="ButtonBase.Click">
                            <BeginStoryboard>
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(ToggleButton.IsChecked)" Storyboard.TargetName="pupMenuButton">
                                        <DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </Grid.Triggers>
                    <ToggleButton x:Name="pupMenuButton" Command="{Binding Path=ActionCommand}" Style="{DynamicResource FlatToggleButtonStyle}">
                        <Grid>
                            <TextBlock>text</TextBlock>
                        </Grid>
                    </ToggleButton>
                    <Popup Placement="Bottom" AllowsTransparency="True" StaysOpen="False"
                               PopupAnimation="Fade" x:Name="pupMenu" 
                                   IsOpen="{Binding ElementName=pupMenuButton, Path=IsChecked}">
                        <ItemsControl ItemsSource="{Binding Path=ListItems}" >
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Button Content="{Binding Text1}" Command="{Binding Path=ActionCommand}" CommandParameter="{Binding}" Style="{DynamicResource ButtonStyleFlatBorder}"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Popup>
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
    

    er wait I just realized what this is doing. You want to close the popup in response to clicking a button in the popup. This would be a good place to use a Restyled MenuItem, because that's exactly what a Menu is for.