Search code examples
c#mvvmcatel

Registered command to commandmanager but it is not firing


I've a View that has a tabcontrol in it. Each tab is a different viewmodel. Above the tab is a Save button, that saves the active tab.

I try to use the CommandManager to pass the click of the button to the viewmodel, but it won't hit.

Here is my setup

using Catel.MVVM;
using Catel.Windows;
namespace Views
public partial class MainWindow : DataWindow
{
private readonly CommandManagerWrapper _commandManagerWrapper;
public MainWindow()
        : base(DataWindowMode.Custom, null, DataWindowDefaultButton.None, true, InfoBarMessageControlGenerationMode.None)
    {
        InitializeComponent();

        _commandManagerWrapper = new CommandManagerWrapper(this);
    }
}

This MainWindow calls a view

<catel:DataWindow x:Class="Views.CustomerOrderBlocksWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:catel="http://catel.codeplex.com"                   
              xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"                    
              xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
              xmlns:b="clr-namespace:TrendzzForYou.Helpers"       
              xmlns:controls="clr-namespace:Views"
              xmlns:helpers="clr-namespace:Helpers"
              xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"  
              ResizeMode="CanResize" SizeToContent="WidthAndHeight"
              WindowStartupLocation="CenterScreen" WindowState="Normal" 
              Icon="/Resources/Graphics/Filters64.png"
              MinHeight="1000" MinWidth="1800">

<catel:DataWindow.Resources>                
    <DataTemplate x:Key="TotalOrderTemplate">
        <controls:CustomerOrderTotalControl DataContext="{Binding CurrentTabContentViewModel}"/>
    </DataTemplate>
    <DataTemplate x:Key="NonDeliverableItemsTemplate">
        <controls:CustomerOrderNonDeliverableControl DataContext="{Binding CurrentTabContentViewModel}"/>
    </DataTemplate>
    <helpers:CustomerOrderBlocksTemplateSelector x:Key="selector"
                                                 TotalOrderTemplate="{StaticResource TotalOrderTemplate}"
                                                 NonDeliverableItemsTemplate="{StaticResource NonDeliverableItemsTemplate}"/>
</catel:DataWindow.Resources>

<Grid Margin="0,0,10,0">
    <Grid.RowDefinitions>            
        <RowDefinition Height="170"/>
        <RowDefinition MinHeight="750"/>            
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="1800"/>
    </Grid.ColumnDefinitions>
    
     <StackPanel>
        <telerik:RadButton Command="{catel:CommandManagerBinding Accept}" ToolTip="Sla gegevens op en voer volgende order in" TabIndex="99" Grid.Row="0">
            <StackPanel Orientation="Horizontal">
                <Image Source="/Resources/Graphics/Accept16.png" Height="16" />
                <telerik:Label Content="Opslaan" />
            </StackPanel>
        </telerik:RadButton>
    </StackPanel>
    
    <telerik:RadTabControl Grid.Row="1" Grid.Column="0" 
                           DisplayMemberPath="Header"
                           ContentTemplateSelector="{StaticResource selector}"                               
                           ItemsSource="{Binding Tabs}"
                           SelectedIndex="{Binding CustomerOrderTab}"/>

and a viewmodel

using Catel;
using Catel.Data;
using Catel.IoC;
using Catel.MVVM;
using Catel.Services;
using System.Collections.Generic;

public class CustomerOrderBlocksWindowViewModel : ViewModelBase
{
   public static readonly PropertyData CustomerOrderTabProperty = RegisterProperty("CustomerOrderTab", typeof(int));
   public static readonly PropertyData TabsProperty = RegisterProperty("Tabs", typeof(List<TabItemModel>));

   public int CustomerOrderTab { get { return GetValue<int>(CustomerOrderTabProperty); } set { SetValue(CustomerOrderTabProperty, value); } }
   public List<TabItemModel> Tabs { get { return GetValue<List<TabItemModel>>(TabsProperty); } set { SetValue(TabsProperty, value);  } }

   public CustomerOrderBlocksWindowViewModel(IUIVisualizerService theVisualizerService, IMessageService theMessageService, IPleaseWaitService thePleaseWaitService)
   {            
       Argument.IsNotNull(() => theVisualizerService);
       Argument.IsNotNull(() => theMessageService);
       Argument.IsNotNull(() => thePleaseWaitService);
 
       uiVisualizer = theVisualizerService;
       messageService = theMessageService;
       pleaseWait = thePleaseWaitService;

       var dependencyResolver = IoCConfiguration.DefaultDependencyResolver;
       commandManager = dependencyResolver.Resolve<ICommandManager>();

       commandManager.CreateCommand("Accept");
    
       UpdateTabs()
   }
    
   private void UpdateTabs()
   {          
        
         Tabs = new List<TabItemModel>()
         {
             new TabItemModel()
             {
                Header="Totaal"
             }
         };
        
         switch(CustomerOrderTab)
         {
            case 0:
                Tabs[0].CurrentTabContentViewModel = new CustomerOrderTotalControlViewModel(uiVisualizer, messageService, pleaseWait, commandManager);
                break;          
            default:
                break;
        }
    }
}

And the CustomerOrderTotalControlViewModel is like

using Catel;
using Catel.Data;
using Catel.MVVM;
using Catel.Services;

namespace ViewModels
{
    public class CustomerOrderTotalControlViewModel : ViewModelBase
    {        
        public Command CmdAccept { get; private set; }
    #region private references
    private IMessageService messageService;
    private IPleaseWaitService pleaseWait;
    private IUIVisualizerService uiVisualizer;
    #endregion

    public CustomerOrderTotalControlViewModel(IUIVisualizerService theVisualizerService, IMessageService theMessageService, IPleaseWaitService thePleaseWaitService, ICommandManager commandManager)
    {            
        Argument.IsNotNull(() => theVisualizerService);
        Argument.IsNotNull(() => theMessageService);
        Argument.IsNotNull(() => thePleaseWaitService);
        Argument.IsNotNull(() => commandManager);

        uiVisualizer = theVisualizerService;
        messageService = theMessageService;
        pleaseWait = thePleaseWaitService;

        CmdAccept = new Command(OnAccept);
        commandManager.RegisterCommand("Accept", CmdAccept, this);
    }

    private void OnAccept()
    {
        WaitScreen("Order opslaan...");            

    }

    private void WaitScreen(string TheMessage)
    {
        if (TheMessage != null)
            pleaseWait.Show(TheMessage);
        else
            pleaseWait.Hide();
    }

}

}

And Finally The TabItemModel:

using Catel.MVVM;

namespace Models
{
public class TabItemModel
{
    /// <summary>
    /// Tab Header text
    /// </summary>
    public string Header { get; set; }

    /// <summary>
    /// Tab content
    /// </summary>
    public IViewModel CurrentTabContentViewModel { get; set; }
}
}

According to the documentation I expect the CmdAccept to fire in CustomerOrderTotalControlViewModel when clicked but it does not.

What do I miss or do wrong

Jeroen


Solution

  • I moved the CommandManagerWrapper from MainWindow.xaml.cs to CustomerOrderBlocks.xaml.cs

    And in CustomerOrderTotalControlViewModel

    changed the RegisterCommand to

    commandManager.RegisterCommand("Accept", CmdAccept);
    

    And it works.

    Not sure why the remove of "this" in the last part of code makes the difference