0

我正在使用 DevExpress Silverlight Menu (AgMenu 8.4) 的免费版本。遗憾的是,此菜单的 MenuItems 没有“Command”和“CommandParameter”属性。

我决定从 MenuItem 类继承并实现两个 DependencyProperties,“Command”和“CommandProperty”。

代码如下所示:

public partial class MenuItem : DevExpress.AgMenu.AgMenuItem
{
    public MenuItem()
    {
        InitializeComponent();
    }

    private Object _CommandParameter = null;

    public Object CommandParameter
    {
        get { return _CommandParameter; }
        set { _CommandParameter = value; } //This one is triggered. This is ok.
    }

    public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(Object), typeof(Gui.CustomControls.MenuItem), new PropertyMetadata(OnCommandParameterChanged));

    private static void OnCommandParameterChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
         //CommandParameter Object is arriving here. That is ok.
    } 


    private ICommand _Command = null;

    public ICommand Command
    {
        get { return _Command; }
        set 
        { 
             //HERE is the problem.
             //This one is NOT triggered. I dont' know why....?
            _Command = value;
        }
    }



    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(Gui.CustomControls.MenuItem), new PropertyMetadata(OnCommandChanged));

    private static void OnCommandChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        //ICommand Object is arriving here. That is also ok.
        //I don't understand, why the ICommand Object is not arriving in the set value prop
    }



}

现在我在我的 XAML 中使用这两个 DP。一个 MenuItem 看起来像这样:

<cc:MenuItem    x:Name              ="_mnuItemLogout"
                            DataContext         ="{Binding Source={StaticResource ViewModel}}"
                            Header              ="{Binding Source={StaticResource MenuProvider}, Path=GetSingleton.LogoutText, Mode=OneWay}" 
                            IsEnabled           ="{Binding Source={StaticResource MenuProvider}, Path=GetSingleton.LogoutEnabled, Mode=OneWay}"
                            Command             ="{Binding Source={StaticResource ViewModel}, Path=Command_FormOpen}" 
                            CommandParameter    ="{gui:FormOpen e=Login}"
                            IsCheckable ="False"
                            >
            </cc:MenuItem>

当我测试我的 silverlight 应用程序时,我假设“Command”和“CommandParameter”设置值属性都被调用,并且值设置为 _Command 和 _CommandParameter,但只调用了 CommandParameter 设置值。

奇怪的是,静态过程“OnCommandChanged”和“OnCommandParameterChanged”都被调用了。在调试时,我可以看到,两个预期的对象(ICommand 和 CommandParameter)都到达了这两个过程。

所以我的问题是:

我做错了什么,ICommand 对象未在“设置 ICommand”属性中设置?

谢谢你。

4

1 回答 1

0

This case is solved. What I needed to do, is not using DependencyProperties, but attached DependencyProperties.

The MenuItem of the DevExpress Silverlight menu now accepts Command and CommandParameter objects. The Command is triggered, when the LeftMouseButtonUp event is fired. The following is the working code. The XAML stays the same (see above). You just need to make a silverlight user control and inherit from DevExpress.AgMenu.AgMenuItem. You then use this as MenuItem, instead of the original.

using System;
using System.Windows;
using System.Windows.Input;

namespace Gui.CustomControls
{
public partial class MenuItem : DevExpress.AgMenu.AgMenuItem
{



    public MenuItem()
    {
        InitializeComponent();
    } 



#region CommandParameter DependencyProperty

    public static Object GetCommandParameter(DependencyObject obj)
    {
        return (Object)obj.GetValue(CommandParameterProperty);
    }

    public static void SetCommandParameter(DependencyObject obj, Object value)
    {
        obj.SetValue(CommandParameterProperty, value);
    }

    public static readonly DependencyProperty CommandParameterProperty =  DependencyProperty.RegisterAttached("CommandParameter", typeof(Object), typeof(Gui.CustomControls.MenuItem), new PropertyMetadata(OnCommandParameterChanged) );

    private static void OnCommandParameterChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        DependencyObject _DependencyObject = (DependencyObject)sender;
        if ((args.NewValue != null) && (_DependencyObject != null))
        {
            MenuItem.SetCommandParameter(_DependencyObject, args.NewValue);
        }
    } 

#endregion

#region Command

    private static void OnCommandChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        DependencyObject _DependencyObject = (DependencyObject)sender;
        ICommand         _ICommand         = (ICommand)args.NewValue;

        if ((_ICommand != null) && (_DependencyObject != null))
        {
            SetCommand(_DependencyObject, _ICommand);
        }
    }

    public static ICommand GetCommand(DependencyObject obj)
    {
        return (ICommand)obj.GetValue(CommandProperty);
    }

    public static void SetCommand(DependencyObject obj, ICommand value)
    {
        obj.SetValue(CommandProperty, value);
    }

    // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(Gui.CustomControls.MenuItem), new PropertyMetadata(OnCommandChanged));

#endregion

#region LeftMouseButtonUp (Command Trigger)

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonUp(e);

        ICommand _ICommand = MenuItem.GetCommand(this);
        Object _CommandParameter = MenuItem.GetCommandParameter(this);

        if (_ICommand != null)
        {
            _ICommand.Execute(_CommandParameter);
        }
    } 

#endregion


}

}

于 2013-05-02T06:44:39.117 回答