将BindableApplicationBarIconButton IsEnabled属性绑定到Relaycommand CanExecute Windows Phone 7.1

时间:2012-05-29 23:45:18

标签: silverlight windows-phone-7 windows-phone-7.1 mvvm-light relaycommand

我正在使用Phone7.Fx R1

以下作品。当用户按下按钮时,系统不会做出反应。这意味着,如果在没有开始游戏的情况下按下停止游戏就没有反应,反之亦然。

但按钮看起来很活跃。我知道我可以将IsEnabled绑定到不同的属性,但我希望它绑定到NewGameCanExecute和StopGameCanExecute。这可能吗?

一些XAML代码:

<Preview:BindableApplicationBarIconButton Command="{Binding NewGame}" IconUri="/images/icons/appbar.add.rest.png" Text="New game" />
        <Preview:BindableApplicationBarIconButton Command="{Binding StopGame}" IconUri="/images/icons/appbar.stop.rest.png" Text="Stop game" />

继电器命令:

public RelayCommand NewGame { get; private set; }
public RelayCommand StopGame { get; private set; }

//Constructor
NewGame = new RelayCommand(NewGameExecute, NewGameCanExecute);
StopGame = new RelayCommand(StopGameExecute, StopGameCanExecute);

void NewGameExecute()
{
    _gameStarted = true;
    _gameControlModel.StartNewGame();
    StopGame.RaiseCanExecuteChanged();
}

bool NewGameCanExecute()
{
    return !_gameStarted;
}

void StopGameExecute()
{      
    _gameControlModel.StopGame();
    _gameStarted = false;
    NewGame.RaiseCanExecuteChanged();
}

bool StopGameCanExecute()
{
    return _gameStarted;
}

一些问答:

问:您是否尝试在CanExecute函数中设置断点以查看它是否被调用?

A:是的。它会被调用,但图标不会显示为灰色,尽管返回false。 如果CanExecute方法返回false,则不执行Execute方法。但我希望图标像普通按钮一样变灰。

我花了一些时间想出一个解决方案,可以在这里找到: http://pastebin.com/MM75xACj

2 个答案:

答案 0 :(得分:1)

这显然是您正在使用的BindableApplicationBarIconButton实施中的错误。

向作者寻求帮助,或亲自调试第三方软件。

答案 1 :(得分:0)

我花了一些时间想出一个解决方案并编辑了applicationbariconbutton类。

namespace Phone7.Fx.Controls
{
    public class BindableApplicationBarIconButton : FrameworkElement, IApplicationBarIconButton
    {
        public int Index { get; set; }

        public static DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(BindableApplicationBarIconButton), new PropertyMetadata(null, OnCommandPropertyChanged));
        private static void OnCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                ((BindableApplicationBarIconButton)d).Command = (ICommand)e.NewValue;
            }
        }

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set {
                    Command.CanExecuteChanged -= ValueOnCanExecuteChanged;
                SetValue(CommandProperty, value);
                Command.CanExecuteChanged += ValueOnCanExecuteChanged;
            }
        }

        private void ValueOnCanExecuteChanged(object sender, EventArgs eventArgs)
        {
            ICommand commandSender = sender as ICommand;
            if(commandSender != null)
            {IsEnabled = commandSender.CanExecute(null);}
        }

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(BindableApplicationBarIconButton), new PropertyMetadata(null, OnCommandParameterPropertyChanged));
        private static void OnCommandParameterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var invokeCommand = d as BindableApplicationBarIconButton;
            if (invokeCommand != null)
            {
                invokeCommand.SetValue(CommandParameterProperty, e.NewValue);
            }
        }
        public object CommandParameter
        {
            get { return GetValue(CommandParameterProperty); }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }


        public static readonly DependencyProperty CommandParameterValueProperty =
          DependencyProperty.RegisterAttached("CommandParameterValue", typeof(object), typeof(BindableApplicationBarIconButton), null);
        public object CommandParameterValue
        {
            get
            {
                var returnValue = GetValue(CommandParameterValueProperty);
                return returnValue;
            }
            set { SetValue(CommandParameterValueProperty, value); }
        }

        public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(BindableApplicationBarIconButton), new PropertyMetadata(true, OnEnabledChanged));

        private static void OnEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                ((BindableApplicationBarIconButton)d).Button.IsEnabled = (bool)e.NewValue;
            }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.RegisterAttached("Text", typeof(string), typeof(BindableApplicationBarIconButton), new PropertyMetadata(OnTextChanged));

        public new static readonly DependencyProperty VisibilityProperty =
           DependencyProperty.RegisterAttached("Visibility", typeof(Visibility), typeof(BindableApplicationBarIconButton), new PropertyMetadata(OnVisibilityChanged));

        private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                var button = ((BindableApplicationBarIconButton)d);
                BindableApplicationBar bar = button.Parent as BindableApplicationBar;

                bar.Invalidate();
            }
        }

        public new Visibility Visibility
        {
            get { return (Visibility)GetValue(VisibilityProperty); }
            set { SetValue(VisibilityProperty, value); }
        }

        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != e.OldValue)
            {
                ((BindableApplicationBarIconButton)d).Button.Text = e.NewValue.ToString();
            }
        }

        public ApplicationBarIconButton Button { get; set; }

        public BindableApplicationBarIconButton()
        {
            Button = new ApplicationBarIconButton();
            Button.Text = "Text";
            Button.Click += ApplicationBarIconButtonClick;
        }

        void ApplicationBarIconButtonClick(object sender, EventArgs e)
        {
            if (Command != null && CommandParameter != null)
                Command.Execute(CommandParameter);
            else if (Command != null)
                Command.Execute(CommandParameterValue);
            if (Click != null)
                Click(this, e);
        }

        public bool IsEnabled
        {
            get { return (bool)GetValue(IsEnabledProperty); }
            set { SetValue(IsEnabledProperty, value); }
        }

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public event EventHandler Click;

        public Uri IconUri
        {
            get { return Button.IconUri; }
            set { Button.IconUri = value; }
        }
    }