Выполнить команду в ListView MenuItem MVVM - PullRequest
0 голосов
/ 02 мая 2019

Почему команда в моем пункте меню Listview не выполняется?

Это код в моем ListView

<ListView ItemsSource="{Binding ListDataCorrection}"  >
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Validate">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Update" Margin="5" Cursor="Hand" Command="{Binding RelativeSource={RelativeSource FindAncestor, 
                                        AncestorType={x:Type ListView}}, Path=DataContext.ValidateCommand}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>

            <ListView.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, 
                                        AncestorType={x:Type ListView}}, Path=DataContext.ValidateAllCommand}">
                    </MenuItem>
                </ContextMenu>
            </ListView.ContextMenu>
        </ListView>

Но странная вещь заключается в том, что ValidateCommand внутри Gridview выполняется.

Пока команды в MenuItem нет.

Что не так с моей привязкой?

И я также проверил правильность имени команды. Если нет, я должен получить сообщение о том, что команда не найдена в ViewModel

Спасибо.

Ответы [ 3 ]

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

Меню (как и всплывающее окно, например) не является частью визуального дерева, так как оно создается по требованию.Так как он не является частью визуального дерева, он не унаследует своих родителей DataContext.Однако вы все равно можете связываться со своим ListView, используя свойство PlacementTarget в вашем связывании:

        <ListView.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Remove" 
                          Command="{Binding Path=PlacementTarget.DataContext.ValidateAllCommand}">
                </MenuItem>
            </ContextMenu>
        </ListView.ContextMenu>
0 голосов
/ 02 мая 2019

Почему команда в моем пункте меню Listview не выполняется?

Поскольку ListView не является визуальным предком MenuItem, то RelativeSource привязки не найден.

Если вы измените AncestorType на ContextMenu и свяжете его с PlacementTarget, он должен работать:

<ContextMenu>
    <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, 
                    Path=PlacementTarget.DataContext.ValidateAllCommand}">
    </MenuItem>
</ContextMenu>
0 голосов
/ 02 мая 2019

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

Моим решением для этого является класс BindingProxy, который выглядит следующим образом:

public class BindingProxy : Freezable
{   
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
        "Data", typeof (object), typeof (BindingProxy), new UIPropertyMetadata(null));

    /// <summary>
    ///     This Property holds the DataContext
    /// </summary>
    public object Data
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
}

В ресурсах вашего представления (UserControl или Window) вы должны добавить прокси, например:

<codeBase:BindingProxy x:Key="proxy" Data="{Binding}"/>

И в вашем MenuItem вы можете использовать его с:

<MenuItem Header="Remove" Command="{Binding Source={StaticResource proxy}, Path=Data.ValidateAllCommand}"/>
...