Прикрепление события щелчка к контекстному меню кнопки в элементе списка

#c# #wpf

#c# #wpf

Вопрос:

Я пытаюсь создать панель загрузки, подобную Chrome.

Допустимый XHTML

Проблема, с которой я сейчас сталкиваюсь, заключается в попытке привязать событие щелчка к контекстному меню кнопки в элементе списка. При нажатии на элемент контекстного меню сообщается, что действие не найдено.

 <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>
  

Я мог бы привязать его к стороне кода (xaml.cs) приложения, но я также теряю представление о том, на какой элемент должен указывать контекст. Для этого я заменил событие щелчка caliburn на обычное событие щелчка. SelectedItem и SelectedItems имеют значение null или empty соответственно.

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

Комментарии:

1. Я немного смущен тем, что вы пытаетесь сделать. Первая фотография — это ListBoxItem кнопка в крайнем правом углу, правильно? И вы хотели бы, чтобы контекстное меню открывалось при нажатии на эту кнопку в крайнем правом углу ListBoxItem ?

2. @kalamazoowho Это именно то, чего я хочу достичь. Так что, похоже, вы не в замешательстве.

3. Я столкнулся с аналогичной проблемой с помощью кода, но я не изменил всплывающее контекстное меню с щелчка правой кнопкой мыши на щелчок левой кнопкой мыши. Вы сказали, что теряете элемент, на который указывает контекст. Знаете ли вы, из каких элементов вы можете выбрать? Например, это всегда будет Button тип, на который будет указывать контекстное меню?

Ответ №1:

Не тестировал, но что-то в этом роде должно открывать контекстное меню при щелчке правой или левой кнопкой мыши:

 <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>
  

Что касается кода, следующее сработало для меня в моей последней попытке с аналогичной проблемой:

 DependencyObject mainDep = new DependencyObject();

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

    while ((dep != null) amp;amp; !(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
        ...
    }
}
  

Дайте мне знать, как это работает для вас

Комментарии:

1. Привет @Hank, спасибо за ваш ответ. Это было не совсем правильно, но оно указало мне правильное направление. Я продолжал искать VisualTree, пока не получил элемент ListBoxItem в качестве родительского элемента.

2. Рад слышать, что это помогло! Итак, вместо поиска Button , как в моем ответе, вы искали ListBoxItem ? Просто хочу убедиться, что ответ обновлен для других, которые могут найти этот пост в поисках ответов