簡體   English   中英

通過MVVM綁定MenuItem的命令

[英]Binding a MenuItem's Command via MVVM

我有一個系統設置,其中使用MVVM體系結構動態填充了ContextMenu層次結構。 除Command以外,我所有的綁定均正常運行。 我的視圖是一個ContextMenu,它指定一個ItemContainerStyle。

ContextMenu的ItemContainerStyle設置為此:

<ContextMenu.ItemContainerStyle>
    <Style TargetType="MenuItem">
        <Setter Property="Command" Value="{Binding Command, Mode=OneWay}"/>
        <Setter Property="IsCheckable" Value="{Binding IsCheckable}"/>
        <Setter Property="IsChecked" Value="{Binding IsChecked, Mode=TwoWay}"/>
        <Setter Property="Header" Value="{Binding Label}"/>
        <Setter Property="ItemsSource" Value="{Binding Children}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsVisible}" Value="False">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ContextMenu.ItemContainerStyle>

到目前為止,還沒有ItemTemplate,因為看來我已經能夠完成樣式中所有所需的功能。

ViewModel必須使用其包裝的模型的實例構造,因此似乎無法將ContextMenu的DataContext顯式設置為ViewModel(編譯器抱怨它沒有無參數的構造函數。該抱怨提到類型轉換器可以也可以使用,盡管我不確定這實際上意味着什么(可以解決問題)。

我的ViewModel的相關部分如下,從以下兩個可綁定到的只讀面向公眾成員開始:

public CommandBinding CommandBinding { get; private set; }
public RoutedCommand Command { get { return CommandBinding.Command as RoutedCommand; } }

CommandBinding及其命令在構造函數中實例化:

CommandBinding = new CommandBinding(new RoutedCommand(), CommandBinding_Executed, CommandBinding_CanExecute);

該構造中引用的方法僅對模型的成員起作用,並實現如下:

void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    if (ContextItem.Command != null) ContextItem.Command(ContextItem);
}

void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = ContextItem.IsEnabled;
    if (ContextItem.ExecuteConditions != null) e.CanExecute = ContextItem.ExecuteConditions.GetInvocationList().Cast<ExecuteCondition>().All(s => s() == true);
}

似乎到Command的綁定實際起作用時,所有項目都顯示為灰色,就像CanExecute返回false一樣。 但是,當我在CanExecute中設置斷點時,執行不會在該點中斷(盡管這可能是由於布局線程引起的?)。 即使我將e.CanExecute顯式設置為true並注釋掉CommandBinding_CanExecute中的其他行,這些項目仍然顯示為灰色。 在XAML中,我嘗試使用Path =和不使用Path =綁定到Command和CommandBinding成員,所有這些都具有相同的效果。 當我將綁定模式設置為OneWayToSource時,調試器會適當地抱怨該屬性為只讀且無法對其進行操作(我希望ViewModel提供該命令,因此是有意的)。

我已經閱讀了其他示例和相關問題的解決方案。 對於那些遵循MVVM模式的應用程序,我無法確定我的實現有何不同。

對於任何解決方案,我必須堅持我仍然可以要求使用模型作為參數來構造ViewModel,並且我希望視圖保留所有XAML,而沒有C#代碼。

似乎CommandBinding是問題所在。 我最終創建了自己的ICommand實現,該實現使我可以在構造時指定Execute和CanExecute委托...效果很好。

這樣就解決了問題,實現起來很簡單,但是對於我為什么無法使用CommandBindings仍然不清楚。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM