捕获Silverlight ControlTemplate按钮命令事件

时间:2012-10-03 14:08:11

标签: silverlight binding telerik command controltemplate

我在获取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";
        }

    }
}

1 个答案:

答案 0 :(得分:1)

您的原始示例似乎应该可行。也许Telerik RadMenu是在视觉树之外构建的?不确定。

尝试更明确地删除未知...命名您的页面(绑定到您的DataContext视图模型)并尝试不同的绑定方法:

<Button Height="70" Style="{StaticResource MenuButtonStyle}" Margin="2"  
                    CommandParameter="{Binding ID}" 
                    Command="{Binding DataContext.MenuCommand, ElementName=ReportPage}"> 
            </Button>