Как получить PlacementTarget в контекстном меню WPF при щелчке элемента с использованием шаблона MVVM

Как получить PlacementTarget выбранного ContextMenu при использовании шаблона MVVM?

Я могу получить PlacementTarget таким образом при использовании события клика MenuItem. Но как это сделать MVVM?

   public void changeGaugeColor(object sender, RoutedEventArgs e)
    {
        MenuItem tempMenuItem = (MenuItem)sender;

        MenuItem mi = (MenuItem)sender;
        bd = (BidirectionalDial)cm.PlacementTarget;

    }

person Dinusha    schedule 08.07.2011    source источник
comment
Разве ваша цель размещения не является частью того же пользовательского элемента управления, к которому вы можете напрямую получить доступ, используя this.yourControlName, что вы пытаетесь сделать?   -  person anivas    schedule 08.07.2011
comment
Вопрос нужно отредактировать! что ты хочешь?   -  person stukselbax    schedule 08.07.2011
comment
Если ваша ViewModel ищет цель размещения, вы делаете это неправильно. Это все прерогатива View, а не ViewModel. Позвольте представлению выполнять всю эту работу из кода программной части.   -  person    schedule 08.07.2011


Ответы (1)


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

Во-первых, назовите свой вид UserControl... Я обычно называю все свои представления This для простоты. Затем, помня, что наша модель представления привязана к DataContext из UserControl, мы можем привязаться к модели представления с помощью {Binding DataContext, ElementName=This}.

Итак, теперь мы можем привязаться к модели представления, мы должны связать это с ContextMenu.DataContext. Я использую свойство Tag объекта с ContextMenu (PlacementTarget) в качестве этой связи, в этом примере Grid:

<DataTemplate x:Key="YourTemplate" DataType="{x:Type DataTypes:YourDataType}">
    <Grid ContextMenu="{StaticResource Menu}" Tag="{Binding DataContext, 
        ElementName=This}">
        ...
    </Grid>
</DataTemplate>

Затем мы можем получить доступ к свойствам и командам модели представления в ContextMenu, привязав свойство ContextMenu.DataContext к свойству PlacementTarget.Tag (из Grid в нашем примере):

<ContextMenu x:Key="Menu" DataContext="{Binding PlacementTarget.Tag, RelativeSource=
    {RelativeSource Self}}">
    <MenuItem Header="Delete" Command="{Binding DeleteFile}" CommandParameter=
        "{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource 
        AncestorType=ContextMenu}}" CommandTarget="{Binding PlacementTarget, 
        RelativeSource={RelativeSource Self}}" />
</ContextMenu>

Обратите внимание на привязку свойства MenuItem.CommandTarget. Установка этого параметра гарантирует, что целевой элемент, для которого вызывается указанная команда, является PlacementTarget или Grid в данном случае.

Также обратите внимание на привязку CommandParameter. Это привязывается к DataContext из PlacementTarget или Grid в данном случае. DataContext из Grid будет унаследовано от DataTemplate, поэтому ваш элемент данных теперь привязан к параметру object в вашем Command, если вы используете некоторую реализацию интерфейса ICommand:

public bool CanExecuteDeleteFileCommand(object parameter)
{
    return ((YourDataType)parameter).IsInvalid;
}

public void ExecuteDeleteFileCommand(object parameter)
{
    Delete((YourDataType)parameter);
}

Или, если вы используете какие-то делегаты RelayCommand непосредственно в вашей модели представления:

public ICommand Remove
{
    get 
    {
        return new ActionCommand(execute => Delete((YourDataType)execute), 
            canExecute => return ((YourDataType)canExecute).IsInvalid); 
    }
}
person Sheridan    schedule 09.03.2013