C # MVVM: Команда MenuItem не выполняется в ViewModel - PullRequest
0 голосов
/ 23 мая 2019

Я создал Delete MenuItem и привязал к нему команду. Теперь у меня проблема, если я нажимаю Delete MenuItem, ничего не происходит. Также, если программа выполняется с помощью отладчика, она никогда не достигнет закрытого void DeleteItem.

XAML:

<ListBox.ItemTemplate>
            <DataTemplate>
                <Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
                    <Border.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Delete"
                                      Command="{Binding Path=DeleteItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType= MenuItem}}">
                                <MenuItem.Icon>
                                    <Label FontFamily="#FontAwesome" Content="&#xf1f8;" />
                                </MenuItem.Icon>
                            </MenuItem>
                        </ContextMenu>
                    </Border.ContextMenu>

ViewModel:

public ICommand DeleteItemCommand { get; set; } 
DeleteItemCommand = new RelayCommand(DeleteItem);

private void DeleteItem(object obj)
{
    try
    {
        // Do Magic
    }
    catch (Exception)
    {
        MessageBox.Show(error);
    }
}

Было бы замечательно, если бы кто-то мог мне помочь или иметь какие-либо идеи, как ее решить, потому что я не могу найти ошибку.

Ответы [ 3 ]

0 голосов
/ 23 мая 2019

ContextMenu не является частью VisualTree, поэтому привязка не выполняется. Вы можете использовать какой-то тип реле, например ContextMenu.PlacementTarget.Tag.Property , в качестве кэша для второго маршрута поиска привязки.

        <ContextMenu>
            <MenuItem Command="my:ImgTreeView.Folders" Header="Folders"
                          IsEnabled="{Binding Path=PlacementTarget.Tag.IsCheckFolder, RelativeSource={RelativeSource AncestorType=ContextMenu}}">
                <MenuItem.Icon>
                        <Image Source="StarFolders.png" />
                </MenuItem.Icon>
            </MenuItem>
            <!-- ... -->
        </ContextMenu>
0 голосов
/ 23 мая 2019

ContextMenu действительно не является частью визуального дерева. Но я думаю, что по этой причине RelativeSource не будет работать, поскольку привязка будет искать визуальное дерево для текста данных. contextMenu не является частью этого визуального дерева, поэтому он не найдет правильный текст данных. Я нашел решение для этого в прошлом, используя прокси-элемент в ресурсах для окна. Затем установите этот прокси-элемент как контент для скрытого управления контентом в окне В menuItem установите для CommandBinding значение Datacontext.DeleteCommand, а для источника статический прокси-элемент ресурса. Это немного хакерски, но это работает. Чтобы показать xaml, попробуйте это: Сначала в ресурсах окна создайте элемент frameworkelement с набором данных datacontext равным тексту данных windows (viewmodel)

<Window.Resources>
        <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
</Window.Resources>

Затем используйте ресурс для содержимого свернутого элемента управления контентом. И установить правильную привязку к пункту меню. Примерно так:

 <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
        <ListBox x:Name="lbTest" Grid.Row="1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
                        <Border.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Delete"
                                          Command="{Binding DataContext.DeleteCommand, Source={StaticResource ProxyElement}}">
                                    <MenuItem.Icon>
                                        <Label FontFamily="#FontAwesome" Content="&#xf1f8;" />
                                    </MenuItem.Icon>
                                </MenuItem>
                            </ContextMenu>
                        </Border.ContextMenu>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Это должно работать. Попробуйте.

0 голосов
/ 23 мая 2019

Не уверен, поможет ли это, но попробуйте использовать Binding вместо Binding Path.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...