我在获取 ICommand(在本例中为 MVVMLight RelayCommand)以从我的 Silverlight 应用程序中的 ControlTemplate 在 ViewModel 中触发时遇到问题。
UI 上的所有内容都正确呈现,但是当单击带有嵌入式按钮的 Telerik RadMenu 项时,ViewModel 上的 LoadTopFiveFaults 方法不会触发。
我应该在 ControlTemplate 中使用 RelativeSource 吗?我错过了什么吗?有没有更好的方法来做到这一点?
控制模板
<ControlTemplate x:Key="SubMenuItem" TargetType="telerik:RadMenuItem">
<Grid>
<Grid x:Name="ContentGrid" Margin="{TemplateBinding Padding}">
<Button Height="70" Style="{StaticResource MenuButtonStyle}" Margin="2"
CommandParameter="{Binding ID}"
Command="{Binding DataContext.MenuCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=navigation:Page}}">
</Button>
</Grid>
</Grid>
</ControlTemplate>
ControlTemplate 按钮样式
<!--MenuButton-->
<Style x:Key="MenuButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#FF1F3B53"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" BorderBrush="Black">
<Grid Margin="1">
<Border x:Name="BackgroundAnimation" Background="#FFF7B000" Opacity="0"/>
<Rectangle x:Name="BackgroundGradient" Fill="{StaticResource PageBackground}"/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" RadiusY="3" RadiusX="3"/>
<Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#FF6DBDD1" StrokeThickness="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Silverlight 页面
<navigation:Page x:Class="QSmart_Cabs_Viewer.Views.Report"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:local="clr-namespace:QSmart_Cabs_Viewer.Views"
xmlns:viewmodels="clr-namespace:QSmart_Cabs_Viewer.ViewModels"
d:DesignWidth="640" d:DesignHeight="480" mc:Ignorable="d"
Title="QSmart Cab Systems Report">
<navigation:Page.Resources>
<viewmodels:ReportPageViewModel x:Key="ViewModel" />
</navigation:Page.Resources>
<Border x:Name="ReportBorder" BorderBrush="Black" BorderThickness="3" CornerRadius="10" Background="{StaticResource PageBackground}">
<Border.Effect>
<DropShadowEffect Direction="318"/>
</Border.Effect>
<Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}" Background="{StaticResource PageBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="33*"/>
<RowDefinition Height="40*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="ConfigTitle" Text="QSmart Cabs Report"
Grid.Row="0" Grid.ColumnSpan="3"
FontSize="32" TextAlignment="Center"
VerticalAlignment="Center" Foreground="{StaticResource ReportHeaders}" />
<Border Grid.Row="0" Grid.Column="3" Grid.RowSpan="3"
BorderBrush="{StaticResource JCBOrangeBoarder}" Background="{StaticResource JCBOrange}"
Margin="3" BorderThickness="5" CornerRadius="20">
<telerik:RadMenu x:Name="Businesses" IconColumnWidth="0" HorizontalAlignment="Left"
ItemsSource="{Binding MenuItems}" ItemContainerStyle="{StaticResource ItemStyle}"
Margin="5,10" Background="{x:Null}" Orientation="Vertical" ClickToOpen="True">
</telerik:RadMenu>
</Border>
</Grid>
</Border>
</navigation:Page>
查看模型
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using QSmart_Cabs_Viewer.Helpers.IOC;
using QSmart_Cabs_Viewer.Helpers.Menus;
using QSmart_Cabs_Viewer.Models;
using QSmart_Cabs_Viewer.ServiceAgents;
using QSmart_Cabs_Viewer.Web.Models;
namespace QSmart_Cabs_Viewer.ViewModels
{
public class ReportPageViewModel : ViewModelBase
{
private const string _topFiveCaption = "Top 5 Faults @ {0}";
private const string _narrativeCaption = "Top Faults @ {0}";
private string _topFiveTitle;
private string _narrativeTitle;
private IDataAgent ServiceAgent { get; set; }
private IMenuBuilder MenuBuilder { get; set; }
public ObservableCollection<MenuModel> MenuItems { get; set; }
public ReadOnlyObservableCollection<CabFaultsCountByBusiness_Result> FaultCountByCustomer { get; set; }
public ICommand MenuCommand { get; set; }
public string TopFiveTitle
{
get
{
return _topFiveTitle;
}
private set
{
_topFiveTitle=string.Format(_topFiveCaption,value);
_narrativeTitle = string.Format(_narrativeCaption, value);
RaisePropertyChanged("TopFiveTitle");
RaisePropertyChanged("NarrativeTitle");
}
}
public string NarrativeTitle
{
get
{
return _narrativeTitle;
}
}
public ReportPageViewModel()
{
if (!IsInDesignMode)
{
ServiceAgent = UnityComponentContainer.ResolvePart<IDataAgent>();
MenuBuilder = UnityComponentContainer.ResolvePart<IMenuBuilder>();
LoadStaticData();
TopFiveTitle = "All Customers";
MenuCommand = new RelayCommand(() => LoadTopFiveFaults());
}
}
private void LoadStaticData()
{
ServiceAgent.GetBusinessUnit((cb) => CreateMenuItems(cb.Entities));
ServiceAgent.GetFaultsCountByBusiness((fcb) =>
FaultCountByCustomer = (ReadOnlyObservableCollection<CabFaultsCountByBusiness_Result>)fcb.Entities);
}
private void CreateMenuItems(IEnumerable<BusinessUnit> items)
{
MenuItems = MenuBuilder.Create(items);
}
private void LoadTopFiveFaults()
{
TopFiveTitle = "Command Fired";
}
}
}