windows phone開發學習–自訂datetimepicker

來源:互聯網
上載者:User

在做開發的時候,經常會碰見設定時間日期的,本來silverlight庫中有calendar控制項,但是windows phone為了壓縮空間砍掉了很多控制項,calendar控制項也自然沒有了。不過好在silverlight toolkit包中提供了一個可以取代calendar的控制項,比如datetimepicker,timepicker,這些控制項放在手機上顯然更合適,基本滿足了大多數情況下的要求。展示的就是datetimepicker控制項

話說回來,沒有一樣東西是萬能的,但是偶爾也有一些例外情況而這些控制項不能很好的解決,例如我要求實現帶“天數,星期,小時”混雜在一起的選項設定時就不行了,為了使用者體驗的一致性,我們也希望選則頁面能像內建的控制項這樣布局,於是改寫就產生了。

其實通過查閱原來控制項的原始碼可以知道大致是如何?的,這其中用到一個最主要的控制項是LoopingSelector,詳細介紹可以看這裡:http://www.cnblogs.com/holyenzou/archive/2011/09/13/2174918.html

其實三個類就能搞定這個控制項,其中兩個類貌似是通用的,格式也是固定的,包括一個抽象類別和一個子類

抽象類別如下:

using System;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Ink;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;using Microsoft.Phone.Controls.Primitives;namespace _365Plus.ItemControls{    // abstract the reusable code in a base class     // this will allow us to concentrate on the specifics when implementing deriving looping data source classes    public abstract class LoopingDataSourceBase : ILoopingSelectorDataSource    {        private object selectedItem;        #region ILoopingSelectorDataSource Members        public abstract object GetNext(object relativeTo);        public abstract object GetPrevious(object relativeTo);        public object SelectedItem        {            get            {                return this.selectedItem;            }            set            {                // this will use the Equals method if it is overridden for the data source item class                      if (!object.Equals(this.selectedItem, value))                {                    // save the previously selected item so that we can use it                        // to construct the event arguments for the SelectionChanged event                        object previousSelectedItem = this.selectedItem;                    this.selectedItem = value;                    // fire the SelectionChanged event                            this.OnSelectionChanged(previousSelectedItem, this.selectedItem);                }            }        }        public event EventHandler<SelectionChangedEventArgs> SelectionChanged;        protected virtual void OnSelectionChanged(object oldSelectedItem, object newSelectedItem)        {            EventHandler<SelectionChangedEventArgs> handler = this.SelectionChanged;            if (handler != null)            {                handler(this, new SelectionChangedEventArgs(new object[] { oldSelectedItem }, new object[] { newSelectedItem }));            }        }        #endregion    }}

子類如下:

using System;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Ink;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;namespace _365Plus.ItemControls{    public class IntLoopingDataSource : LoopingDataSourceBase    {        private int minValue;        private int maxValue;        private int increment;        public IntLoopingDataSource()        {            this.MaxValue = 10;            this.MinValue = 0;            this.Increment = 1;            this.SelectedItem = 0;        }        public int MinValue        {            get { return this.minValue; }            set            {                if (value >= this.MaxValue)                {                    throw new ArgumentOutOfRangeException("MinValue", "MinValue cannot be equal or greater than MaxValue");                }                this.minValue = value;            }        }        public int MaxValue        {            get { return this.maxValue; }            set            {                if (value <= this.MinValue)                {                    throw new ArgumentOutOfRangeException("MaxValue", "MaxValue cannot be equal or lower than MinValue");                }                this.maxValue = value;            }        }        public int Increment        {            get { return this.increment; }            set            {                if (value < 1)                {                    throw new ArgumentOutOfRangeException("Increment", "Increment cannot be less than or equal to zero");                }                this.increment = value;            }        }        public override object GetNext(object relativeTo)        {            int nextValue = (int)relativeTo + this.Increment;            if (nextValue > this.MaxValue)            {                nextValue = this.MinValue;            }            return nextValue;        }        public override object GetPrevious(object relativeTo)        {            int prevValue = (int)relativeTo - this.Increment;            if (prevValue < this.MinValue)            {                prevValue = this.MaxValue;            }            return prevValue;        }    }}

使用的時候只需要建立子類對象,設定參數即可

例如我這裡就實現了自訂“天數-小時-分鐘”的控制項

前台xaml代碼:

<UserControl x:Class="_365Plus.ItemControls.DateTimeNumberPicker"    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"    mc:Ignorable="d"    FontFamily="{StaticResource PhoneFontFamilyNormal}"    FontSize="{StaticResource PhoneFontSizeNormal}"    Foreground="{StaticResource PhoneForegroundBrush}"    d:DesignHeight="480" d:DesignWidth="480" xmlns:toolkitPrimitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls.Toolkit">        <Grid x:Name="LayoutRoot">        <Grid.ColumnDefinitions>            <ColumnDefinition Width="*" />            <ColumnDefinition Width="*" />            <ColumnDefinition Width="*" />        </Grid.ColumnDefinitions>                <toolkitPrimitives:LoopingSelector FontSize="48" HorizontalAlignment="Left" ItemMargin="20,9,9,20" ItemSize="100,100" Grid.Column="0" Name="selectorDay" Width="90"   />        <toolkitPrimitives:LoopingSelector FontSize="48" HorizontalAlignment="Left" ItemMargin="20,9,9,20" ItemSize="100,100" Grid.Column="1" Name="selectorHour" Width="90"  />        <toolkitPrimitives:LoopingSelector FontSize="48" HorizontalAlignment="Left" ItemMargin="20,9,9,20" ItemSize="100,100" Grid.Column="2" Name="selectorMinute" Width="90" />        <TextBlock FontSize="24" HorizontalAlignment="Right" Grid.Column="0" Text="天" TextWrapping="Wrap" VerticalAlignment="Center" Width="50" />        <TextBlock FontSize="24" HorizontalAlignment="Right" Grid.Column="1" Text="小時" TextWrapping="Wrap" VerticalAlignment="Center" Width="50" />        <TextBlock FontSize="24" HorizontalAlignment="Right" Grid.Column="2" Text="分鐘" TextWrapping="Wrap" VerticalAlignment="Center" Width="50" />    </Grid></UserControl>

後台cs代碼:

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;using Microsoft.Phone.Controls.Primitives;namespace _365Plus.ItemControls{    public partial class DateTimeNumberPicker : UserControl    {        /// <summary>        /// 選擇天、時、分的控制項        /// </summary>        public DateTimeNumberPicker()        {            InitializeComponent();            selectorDay.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 30, SelectedItem = 0 };            selectorHour.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 23, SelectedItem = 0 };            selectorMinute.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 59, SelectedItem = 0 };            selectorDay.IsExpandedChanged += OnSelectorIsExpandedChanged;            selectorHour.IsExpandedChanged += OnSelectorIsExpandedChanged;            selectorMinute.IsExpandedChanged += OnSelectorIsExpandedChanged;            _selectorDay = selectorDay;            _selectorHour = selectorHour;            _selectorMinute = selectorMinute;        }        public static readonly DependencyProperty ColorProperty = DependencyProperty.RegisterAttached("MaxDay", typeof(int), typeof(DateTimeNumberPicker), new PropertyMetadata((int)30, DateTimeNumberPicker.OnMaxDayPropertyChanged));        private static void OnMaxDayPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)        {            DateTimeNumberPicker control = d as DateTimeNumberPicker;            if (control != null )            {                control.selectorDay.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = (int)e.NewValue, SelectedItem = 0 };            }        }        public int MaxDay        {            get            {                return (int)GetValue(ColorProperty);            }            set            {                SetValue(ColorProperty, value);            }        }        private void OnSelectorIsExpandedChanged(object sender, DependencyPropertyChangedEventArgs e)        {            if ((bool)e.NewValue)            {                // Ensure that only one selector is expanded at a time                selectorDay.IsExpanded = (sender == selectorDay);                selectorHour.IsExpanded = (sender == selectorHour);                selectorMinute.IsExpanded = (sender == selectorMinute);            }        }        private LoopingSelector _selectorDay;        public LoopingSelector SelectorDay        {            get { return _selectorDay; }            //set { _selectorDay = value; }        }        private LoopingSelector _selectorHour;        public LoopingSelector SelectorHour        {            get { return _selectorHour; }            //set { _selectorHour = value; }        }        private LoopingSelector _selectorMinute;        public LoopingSelector SelectorMinute        {            get { return _selectorMinute; }            //set { _selectorMinute = value; }        }    }    }

設定顯示介面上的初始值就在這三句

 selectorDay.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 30, SelectedItem = 0 };            selectorHour.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 23, SelectedItem = 0 };            selectorMinute.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 59, SelectedItem = 0 };

實現效果如下

通過這種方法,可以做出很多類似的控制項,不過為了布局美觀,最好不要超過三欄。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.