The Now Markup Extension – C# code

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Threading;

namespace i4.WPF.Custom.MarkupExtensions
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use these Markup Extensions in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:i4.WPF.Custom.MarkupExtensions"
    /// or
    ///     xmlns:MyNamespace="http://www.intelligence4.net/WPF/Custom/MarkupExtensionsssdk/2009/xaml"
    ///
    ///
    /// Step 1b) Using these Markup Extensions in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:i4.WPF.Custom.MarkupExtensions;assembly=i4MarkupExtensions"
    /// or
    ///     xmlns:MyNamespace="http://www.intelligence4.net/WPF/Custom/MarkupExtensionsssdk/2009/xaml"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your Markup Extensions in the XAML file.
    ///
    ///     MyNamespace:Now
    ///
    /// XAML Markup Extension to bind dependency property (DateTime or String)    
    /// to the current date and time (updated each second)    
    /// </summary>
    [MarkupExtensionReturnType(typeof(string))]  
    public class NowExtension : MarkupExtension
    {
        #region State         

        // default, full date format (current culture)        
        private readonly string m_format = CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern;
        // for empty constructor we return the DateTime        
        private readonly bool m_returnDate;
        private DependencyObject m_targetObject;
        private DependencyProperty m_targetProperty;
        private DispatcherTimer m_timer;

        #endregion

        #region Constructors         

        /// <summary>        
        /// Create new Now Extension that return the         
        /// current DateTime (DateTime.Now)        
        /// </summary>        
        public NowExtension()
        {
            m_returnDate = true;
        }

        /// <summary>        
        /// Create new Now Extension that return the         
        /// current DateTime formatted (calling ToString         
        /// with m_format)        
        /// </summary>        
        public NowExtension(string format)
        {
            if (!string.IsNullOrEmpty(format))
            {
                m_format = format;
            }
        }

        #endregion

        /// <summary>        
        /// Overrides MarkupExtension.ProvideValue to return         
        /// the current datetime and hook a timer to update the         
        /// target propery each second         
        /// (using DispatcherTime with Background priority)        
        /// </summary>        
        /// <param name="serviceProvider"></param>        
        /// <returns></returns>        
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var targetHelper = (IProvideValueTarget) serviceProvider.GetService(typeof (IProvideValueTarget));
            m_targetObject = targetHelper.TargetObject as DependencyObject;
            m_targetProperty = targetHelper.TargetProperty as DependencyProperty;
            m_timer = new DispatcherTimer(DispatcherPriority.Background) {Interval = TimeSpan.FromSeconds(1)};
            m_timer.Tick += m_timer_Tick;
            m_timer.Start();
            return m_returnDate ? DateTime.Now.ToString() : GetNowValue();
        }

        /// <summary>
        /// Gets the now value.
        /// </summary>
        /// <returns></returns>
        protected virtual string GetNowValue()
        {
            return DateTime.Now.ToString(m_format);
        }

        /// <summary>
        /// Handles the Tick event of the m_timer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void m_timer_Tick(object sender, EventArgs e)
        {
            if (m_targetObject == null || m_targetProperty == null) return;
            object value = GetNowValue();
            if (m_returnDate)
            {
                value = DateTime.Now;
            }
            m_targetObject.SetValue(m_targetProperty, value.ToString());
        }
    }
}
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: