Master Master - 1 month ago 17
C# Question

Attaching Click Event To Button's Context MenuItem Within ListBoxItem

I'm trying to create a download bar like chrome.

Valid XHTML

The issue I'm currently having is trying to bind the click event to the button's context menu within the listboxitem. When the context menuitem is clicked, it says the action is not found.

<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button BorderBrush="Transparent" BorderThickness="0" telerik:StyleManager.Theme="Windows8" Click="ButtonBase_OnClick">
<StackPanel Name="Panel" SnapsToDevicePixels="True"
Orientation="Horizontal" Margin="1 0"
Height="30">

<ContentControl Margin="0 0 10 0" Height="20">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate" Value="{StaticResource Icons.File}"></Setter>
</Style>
</ContentControl.Style>
</ContentControl>

<TextBlock Foreground="Black" Text="{Binding FileName}"
VerticalAlignment="Center"
TextAlignment="Center"
Margin="1 0 0 0"/>

<Button x:Name="ExpandButton" Background="Transparent" Click="ExpandButton_OnClick" BorderThickness="0" VerticalAlignment="Center" ContextMenuService.IsEnabled="false">
<Button.ContextMenu>
<ContextMenu x:Name="popup">
<MenuItem Header="Open" cal:Message.Attach="[Click] = [Open($this)]"></MenuItem>
</ContextMenu>
</Button.ContextMenu>
<ContentControl ContentTemplate="{StaticResource Icons.ArrowUp}" Width="10" Height="10" Margin="2" VerticalAlignment="Center"/>
</Button>
<Rectangle Width="2" Fill="Gray" Margin="0 0 0 0"/>
</StackPanel>
</Button>
</ControlTemplate>


I could bind it behind code(xaml.cs) side of the application but I also lose track of what item is the context suppose to point to. To do that, i replaced caliburn's click event with a regular Click event. The SelectedItem and SelectedItems is null or empty, respectively.

private void MenuItem_OnClick(object sender, RoutedEventArgs e)
{
var originalSource = e.OriginalSource;
var selectedItem = FileListBox.SelectedItem;
var SelectedItems = FileListBox.SelectedItems;
}

Answer

Haven't tested but something along these lines should open the context menu on right or left click:

<Button x:Name="ExpandButton" Background="Transparent" Click="ContextMenu_Click" BorderThickness="0" VerticalAlignment="Center" ContextMenuService.IsEnabled="false">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <EventTrigger RoutedEvent="Click">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
                                    <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu x:Name="popup" MenuItem.Click="menuItem_Click">
                        <MenuItem  Header="Open" cal:Message.Attach="[Click] = [Open($this)]"></MenuItem>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </Button.Style>
    <ContentControl ContentTemplate="{StaticResource Icons.ArrowUp}" Width="10" Height="10" Margin="2" VerticalAlignment="Center"/>
</Button>

As for the code-behind, the following worked for me in my last tug with a similar issue:

DependencyObject mainDep = new DependencyObject();

private void ContextMenu_Click(object sender, RoutedEventArgs e)
{
    DependencyObject dep = (DependencyObject)e.OriginalSource;

    while ((dep != null) && !(dep is ListBoxItem))
    {
        dep = VisualTreeHelper.GetParent(dep);
    }
    mainDep = dep;
}
private void menuItem_Click(object sender, RoutedEventArgs e)
{
    DependencyObject dep = mainDep;

    if (dep is ListBoxItem)
    {
        ...
           DO your stuff here
        ...
    }
}

Let me know how these work for you

Comments