嗨,朋友们, 我正在开发 MVVM WPF应用程序,我需要为 TelerikRadTab 控制 SelectionChanged 事件执行事件,我知道使用MVVM灯它很简单EventToCommand行为,但因为我正在使用MVVM框架(Link) 我必须使用@ Link建议的交互式触发器。
对于下面的内容,我添加了来自
的交互式dll参考C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\Silverlight\v4.0
在XAML中我包括
xmlns:I="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<Command:ChangePropertyOnTarget
Target="{Binding}" PropertyName="SelectedItems"
Value="{Binding SelectedItems, ElementName=ItemsToChoose}" />
</i:EventTrigger>
</i:Interaction.Triggers>
当我构建应用程序时,我收到以下错误。
XML名称空间“Link”中不存在属性“EventName”。
对此提出任何建议或帮助都会有很大帮助。
答案 0 :(得分:0)
我正在使用mvvm light但不需要经常使用事件命令功能。我用稍微不同的方式管理了你的相同功能:
<telerik:RadTabControl Template="{StaticResource TabControlTemplate}"
ItemsSource="{Binding TabbedViewModels }" SelectedItem="{Binding ActiveTabbedViewModel, Mode=TwoWay}"
ItemTemplate="{StaticResource TabItemTemplate}" Style="{StaticResource RadTabControlStyleBorderless}" />
所以在主窗口viewmodel上我有一个viewmodels集合,每个标签项目一个,我绑定到控件的项目源。 然后我将selecteditem绑定到主视图模型上的属性。然后在该属性的setter中,我能够执行在SelectionChangedEvent中需要执行的任何特定操作。 在我的例子中,选项卡的视图模型是根据用户启动的内容动态加载的,每个选项都可能完全不同,因此它们都可以从公共基类继承,尽管您也可以使用接口。 因此,该集合是该bas类的ObservableCollection,而且selectedItem绑定的ActiveTabbedViewModel属性也属于该类型。
可能或可能不适合您的方案,但通过使用此方法,我不需要任何交互触发器
编辑:进入更多细节 - 害怕我不知道有一个博客指向你,所以会更多地解释我是如何接近这个
使用TabControl和内容框架的MainPage.xaml。 MainPageViewModel是主页的视图模型。它有一个名为TabbedViewModels的属性,它是TabbedWindowViewModelBase的ObservableCollection(我为此目的创建的一个类)
/// <summary>
/// Gets or sets a collection of TabbedViewModels - each one will be represented by a tab on the top bar of the main window
/// </summary>
public ObservableItemCollection<CastleTabbedWindowViewModelBase> TabbedViewModels
{
get
{
return this.tabbedViewModels;
}
set
{
this.tabbedViewModels = value;
this.RaisePropertyChanged(() => this.TabbedViewModels);
}
}
/// <summary>
/// Gets or sets the Active Tab - is bound to the Tab bars SelectedItem - when changing to
/// another tab / view model it sets the page menu item to the correct one for that view model
/// </summary>
public CastleTabbedWindowViewModelBase ActiveTabbedViewModel
{
get
{
return this.activeTabbedViewModel;
}
set
{
this.activeTabbedViewModel = value;
this.RaisePropertyChanged(() => this.ActiveTabbedViewModel);
if (value != null)
{
// when the active tab has changed want to ensure we open the previously opened page that the new tab was on
value.DoSomething();
}
}
}
此时,这取决于您的方案的复杂程度。如果您具有相同的视图但只是更改数据,那么您的视图可以绑定到ActiveTabbedViewModel,因为它会引发propertychanged事件,它将自动刷新绑定并显示与新选项卡相关的数据。你可以使用子视图模型上的DoSomething来加载它的数据 - 你只需要这样做一次,除非你想要刷新它。
根据您的描述,解决此问题的方法之一是在下面创建TabbedWindowViewModel类:`
public class TabbedWindowViewModel :ViewModelBase
{
private RelayCommand<NavigationEventArgs> navigationCommand;
/// <summary>
/// Gets or sets the position /order that this tab item is relative to the other tab items
/// </summary>
public int MenuOrder { get; set; }
/// <summary>
/// Gets or sets the Navigation Id
/// </summary>
public int NavigationId { get; set; }
/// <summary>
/// Gets or sets the Title that will be displayed for this tab item
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets the navigation target that will be navigated to when the tab item is clicked
/// </summary>
public string NavigationTarget { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the tab item is enabled
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Gets the command for regular navigation.
/// </summary>
public virtual ICommand NavigationCommand
{
get
{
return this.navigationCommand
??
(this.navigationCommand =
new RelayCommand<NavigationEventArgs>(
this.ExecuteNavigationCommand, x => this.IsEnabled));
}
}
public void DoSomething()
{
//do whatever you need to
//then navigate to the correct page
this.NavigationCommand.Execute(null);
}
private void ExecuteNavigationCommand(NavigationEventArgs e)
{
NavigationManager.NavigateToView(this.NavigationTarget);
}
}
请注意,NavigationManager是一个帮助导航的静态助手类。 然后,您可能导航到的每个视图都将从MainPage继承datacontext - 因此您有两个选择 - 您可以在TabbedWindoViewModel上拥有DataViewModel属性,并通过ActiveTabbedWindow.DataViewModel将所有内容绑定到该属性。或者,像我们一样,在主视图模型上为每个子视图模型创建一个属性,并直接绑定到该属性:
public SummaryViewModel SummaryViewModel
{
get
{
return this.summaryViewModel
?? (this.summaryViewModel = (SummaryViewModel)ViewModelFactory.GetPageViewModel<SummaryViewModel>());
}
}
希望这会有所帮助......