WPF контекстни менюта в Caliburn Micro

Опитвам се да получа контекстно меню в ListBox ItemTemplate, за да извикам метод на модела на родителския изглед, като предавам елемента, върху който е щракнато, като параметър. Това работи за други бутони в шаблона на елемента, но за контекстното меню изглежда не работи.

Имам следния xaml (съкратен за яснота):

<ListBox>
    <ListBox.GroupStyle>
        <GroupStyle>
            ...
        </GroupStyle>
    </ListBox.GroupStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ContextMenu>
                    <ContextMenu Name="cm">
                        <MenuItem Header="Open" 
                                  cal:Message.Attach="Open($dataContext)">

                        </MenuItem>
                </Grid.ContextMenu>

                <TextBlock VerticalAlignment="Center" >
                    .. text..
                </TextBlock>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Имам чувството, че това е свързано с факта, че визуалното дърво е различно, така че Caliburn не може да разреши метода надеждно. Сигурен съм, че това е често срещан проблем и опитах няколко от нещата, които намерих онлайн, но изглежда нищо не работи.

Някакви идеи??


person jonnii    schedule 12.04.2012    source източник


Отговори (2)


Използвайки информацията, която намерих на сайта на Caliburn Micro, промених вашия XAML така, че да изглежда така:

  <Grid Background="White" HorizontalAlignment="Stretch" Height="200" Name="GridLayout">       
    <ListBox x:Name="ListBoxItems">            
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Tag="{Binding DataContext, ElementName=GridLayout}">
                    <Grid.ContextMenu>
                        <ContextMenu Name="cm" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Open" 
                              cal:Message.Attach="Open($dataContext)">
                            </MenuItem>
                        </ContextMenu>
                    </Grid.ContextMenu>

                    <TextBlock VerticalAlignment="Center" >
                .. text..
                    </TextBlock>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

И моят модел на изглед:

    public List<string> ListBoxItems { get; set; }
    public ShellViewModel()
    {
        ListBoxItems = new List<string> {"One", "Two", "Three"};          
    }

    public void Open(object source)
    {
        MessageBox.Show((string) source);
    }

Отваряне беше извикано успешно със съответните низове от списъчното поле.

person Jason Massey    schedule 23.04.2012
comment
Чудя се защо това не беше прието. Много ми помогна, благодаря. - person Jony Adamit; 08.05.2015

Като добавим към отговора на Джейсън, ако ще използвате същия контекст на данни като контролата, тогава можете просто да свържете DataContext вместо Tag

<Grid>
    <Grid.ContextMenu>
        <ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
            <MenuItem Header="Open" 
                      cal:Message.Attach="Open($source)">
            </MenuItem>
        </ContextMenu>
    </Grid.ContextMenu>
</Grid>

$source Действителният FrameworkElement, който е задействал съобщението за действие

Можете да видите повече информация за $source конвенцията тук: https://caliburnmicro.com/documentation/cheat-sheet

person Kao    schedule 17.07.2019