PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/V4/PrismLibrary/Phone/Prism.Interactivity/ApplicationBarButtonCommand.cs

#
C# | 159 lines | 89 code | 18 blank | 52 comment | 6 complexity | 481725da7888a2ded138199b6ef68fe5 MD5 | raw file
  1//===================================================================================
  2// Microsoft patterns & practices
  3// Composite Application Guidance for Windows Presentation Foundation and Silverlight
  4//===================================================================================
  5// Copyright (c) Microsoft Corporation.  All rights reserved.
  6// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9// FITNESS FOR A PARTICULAR PURPOSE.
 10//===================================================================================
 11// The example companies, organizations, products, domain names,
 12// e-mail addresses, logos, people, places, and events depicted
 13// herein are fictitious.  No association with any real company,
 14// organization, product, domain name, email address, logo, person,
 15// places, or events is intended or should be inferred.
 16//===================================================================================
 17using System;
 18using System.Windows;
 19using System.Windows.Data;
 20using System.Windows.Input;
 21using System.Windows.Interactivity;
 22using Microsoft.Phone.Controls;
 23using Microsoft.Phone.Shell;
 24
 25namespace Microsoft.Practices.Prism.Interactivity
 26{
 27    /// <summary>
 28    /// Associates a command to an <see cref="ApplicationBarIconButton"/>.
 29    /// </summary>
 30    [CLSCompliant(false)]
 31    public class ApplicationBarButtonCommand : Behavior<PhoneApplicationPage>
 32    {
 33        ///<summary>
 34        /// The parameter to use when calling methods on the <see cref="ICommand"/> interface.
 35        ///</summary>
 36        public static readonly DependencyProperty CommandParameterProperty =
 37            DependencyProperty.Register("CommandParameter",
 38                                        typeof(string),
 39                                        typeof(ApplicationBarButtonCommand),
 40                                        new PropertyMetadata(HandleCommandChanged));
 41
 42        /// <summary>
 43        /// The binding for <see cref="ICommand"/> to invoke based on the ApplicationBarIconButton's events.
 44        /// </summary>
 45        public static readonly DependencyProperty CommandBindingProperty =
 46            DependencyProperty.Register("CommandBinding",
 47                                        typeof(ICommand),
 48                                        typeof(ApplicationBarButtonCommand),
 49                                        new PropertyMetadata(HandleCommandChanged));
 50
 51        private ClickCommandBinding binding;
 52
 53        /// <summary>
 54        /// The text indicating which <see cref="ApplicationBarIconButton"/> to bind with.
 55        /// </summary>
 56        public string ButtonText { get; set; }
 57
 58        /// <summary>
 59        /// The <see cref="ICommand"/> associated with the instance of ApplicationBarIconButton. 
 60        /// </summary>
 61        public ICommand CommandBinding
 62        {
 63            get { return (ICommand)GetValue(CommandBindingProperty); }
 64            set { SetValue(CommandBindingProperty, value); }
 65        }
 66
 67        /// <summary>
 68        /// the string based parameter to be passed to the <see cref="ICommand"/>.
 69        /// </summary>
 70        public string CommandParameter
 71        {
 72            get { return (string)GetValue(CommandParameterProperty); }
 73            set { SetValue(CommandParameterProperty, value); }
 74        }
 75
 76        /// <summary>
 77        /// Called after the behavior is attached to an AssociatedObject.
 78        /// </summary>
 79        /// <remarks>
 80        /// Override this to hook up functionality to the AssociatedObject.
 81        /// </remarks>
 82        protected override void OnAttached()
 83        {
 84            base.OnAttached();
 85            this.CreateBinding();
 86        }
 87
 88        /// <summary>
 89        /// Invoked when the <see cref="CommandBinding"/> changes.
 90        /// </summary>
 91        protected void OnCommandChanged()
 92        {
 93            this.CreateBinding();
 94        }
 95
 96        private static void HandleCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
 97        {
 98            ((ApplicationBarButtonCommand)sender).OnCommandChanged();
 99        }
100
101        private void CreateBinding()
102        {
103            if (this.CommandBinding == null || this.AssociatedObject == null) return;
104
105            if (this.binding != null)
106            {
107                this.binding.Detach();
108            }
109
110            this.binding = new ClickCommandBinding(
111                this.AssociatedObject.ApplicationBar.FindButton(this.ButtonText),
112                (ICommand)this.CommandBinding,
113                () => this.CommandParameter);
114        }
115
116        /// <summary>
117        /// Binds an <see cref="ApplicationBarIconButton"/> to a <see cref="ICommand"/>.
118        /// </summary>
119        private class ClickCommandBinding
120        {
121            private readonly ICommand command;
122            private readonly ApplicationBarIconButton iconButton;
123            private readonly Func<object> parameterGetter;
124
125            /// <summary>
126            /// 
127            /// </summary>
128            /// <param name="iconButton"></param>
129            /// <param name="command"></param>
130            /// <param name="parameterGetter"></param>
131            public ClickCommandBinding(ApplicationBarIconButton iconButton, ICommand command, Func<object> parameterGetter)
132            {
133                this.command = command;
134                this.iconButton = iconButton;
135                this.parameterGetter = parameterGetter;
136                this.iconButton.IsEnabled = this.command.CanExecute(parameterGetter());
137
138                this.command.CanExecuteChanged += this.CommandCanExecuteChanged;
139                this.iconButton.Click += this.IconButtonClicked;
140            }
141
142            public void Detach()
143            {
144                this.iconButton.Click -= this.IconButtonClicked;
145                this.command.CanExecuteChanged -= this.CommandCanExecuteChanged;
146            }
147
148            private void IconButtonClicked(object s, EventArgs e)
149            {
150                this.command.Execute(this.parameterGetter());
151            }
152
153            private void CommandCanExecuteChanged(object s, EventArgs ea)
154            {
155                this.iconButton.IsEnabled = this.command.CanExecute(this.parameterGetter());
156            }
157        }
158    }
159}