[英]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.