我有一个视图,其中有一个选项卡控件。每个选项卡都是不同的视图模型。选项卡上方是保存按钮,用于保存活动选项卡。
我试图使用CommandManager将按钮的点击传递给视图模型,但它不会命中。
这是我的设置
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);
}
}
此主窗口调用视图
<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}"/>
和视图模型
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;
}
}
}
CustomerOrderTotalControlViewModel类似
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();
}
}
}
最后是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; }
}
}
根据文档,我希望单击时在CustomerOrderTotalControlViewModel中激发CmdAccept,但它没有。
我错过了什么或做错了什么
Jeroen
这有点难说,但你检查了Catel日志记录了吗?可能的情况是在视图模型ctor中创建的命令。此时,视图可能已经加载,并且CommandManagerBinding已经完成了它的一部分。
为了解决这个问题,建议在应用程序启动时注册所有命令(如果是插件/扩展,则在插件初始化时注册(。然后,可以在视图模型的ctor中设置绑定到此命令的操作或命令。
以下是应用程序范围命令的几个示例:
https://github.com/WildGums/LogViewer/tree/develop/src/LogViewer/Commands
一些旁注:
- 我注意到您正在手动解析ICommandManager,但我建议也使用依赖项注入来注入ICommandManager
- 我看到你在用";长记数法";Catel属性。我建议调查一下Catel。Fody,这样您就可以简化属性定义和Catel的整体开发
我将CommandManagerWrapper从MainWindow.xaml.cs移动到CustomerOrderBlocks.xaml.cs
在CustomerOrderTotalControlViewModel 中
将RegisterCommand更改为
commandManager.RegisterCommand("Accept", CmdAccept);
它是有效的。
不确定为什么删除";这个";在代码的最后一部分产生差异