设为首页 收藏本站
查看: 1046|回复: 0

Windows Phone 7 不温不火学习之《数据绑定与应用程序栏》

[复制链接]

尚未签到

发表于 2015-5-9 10:52:55 | 显示全部楼层 |阅读模式
  还是以上篇导航为基础,完善导航的页面并为导航的页面绑定数据和显示数据。
  这篇学习笔记主要记录两个点,分别为如下:

  • 基于Silverlight 的Windows Phone 数据绑定
  • 为应用程序添加程序栏,额外记录显示和隐藏系统托盘(System.Tray)的代码
1.数据绑定
  数据绑定为基于Silverlight 的应用程序提供了一个简单的方式来实现显示和数据之间交互。数据显示从数据管理中分离出来。用户界面与数据模型之间的连接或者绑定,允许数据在两者之间流动。不一个绑定被建立,数据发生改变,被绑定到数据的UI(用户界面 )元素能自动发生改变。这本篇 学习笔记将针对Silverlight 提供的控件DataList 为原型讲述如何绑定数据和删除数据。下面的图显示了绑定的概念:
DSC0000.png
  上图可以分为绑定目标和绑定源。

  • 绑定目标代表绑定的对象是UI控件,所以必须控件是FrameworkElement的任何一个DependencyProperty(提供快速的方法计算值,可与其他动态数据交互)。
  • 绑定来源包含了来源和目标之间的数据流的数据。来源可以是任何运行于CLR的对象,包括目标元素本身或者其他UI元素。
  • 数据流的方向。Binding 对象的Mode属性设置了数据流的方向。分为三种方向:OneTime---目标控件属性只是更新一次,以后的更新会被忽略。oneWay--数据对象的值会同步到目标控件的属性,但是目标控件的属性的改变不会同步到数据对象中。TwoWay--目标控件的属性和数据对象的值相互同步。
  • 可选的值转换器,它被应用于经过值转换器传递的数据。值转器是一个类,它实现了IValueConverter。
  原理大致如上,下面看一下要实现的效果图:
DSC0001.png
  如图,点击图中画红圈的连接,将会导航到一个放置DataList的数据列表,DataList放置了一列带图片和文字的数据,选中某项则让删除按钮可用,可以指定删除某项数据,并实时更新到列表中,界面效果如下:
DSC0002.png
  
  绑定数据原理:
  为了保证引用的集合发生改变时数据绑定机制也能使集合接收通知,Silverlight 使用了事件机制。数据绑定引擎期望当一个集合的值改变时,所发生的事件是CollectionChanged ,该事件被定义为如下:
  


event NotifyCollectionChangedEventHandler CollectionChanged;  
  这个集合的实现应该是集合的每一个改变(添加/编辑/移除集合的成员,程序顺序,等)都会被触发到事件。引用事件响应变化。这个事件被定义到INotifyCollectionChanged 接口中。 为使数据绑定能自动更新到集合,应该创建自己的集合并实现这个接口。在Silverlight 类库中提供了两个集合,这两个集合实现了这个接口,我们可以很放心的拿来使用,分别为:ObservableCollection和ReadOnlyObservableCollection 。

  • ObservableCollection -代表了一个动态数据集。它会为集合中的项发生添加,移除或者整个列表被刷新等情况实时提供通知。
  • ReadOnlyObservableCollection -代表了一个可读的ObservableCollection。
  Tip:两个类的数据绑定机制会对更新己经绑定到集合的对象时触发的事件做出响应。
  
  实现这个集合之前,我们有必要先完成一个Phots 的属性集,代码如下:
  


  public class Photo : INotifyPropertyChanged
    {
        private string _Filename;
        public string Filename
        {
            get { return _Filename; }
            set
            {
                _Filename = value;
                NotifyPropertyChanged("FileName");
            }
        }
        private BitmapImage _Image;
        public BitmapImage Image
        {
            get { return _Image; }
            set
            {
                _Image = value;
                NotifyPropertyChanged("Image");
            }
        }
        private void NotifyPropertyChanged(string propertyName)
        {
            if (null != PropertyChanged)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }  
  TIP: INotifyPropertyChanged ,是一个接口实现它是为了在数据改变的时候能够广播出去,通过属性名称通知哪个属性名称发生了变化。
  另外我们还需要一个工具来,用来通过资源的URI将文件转为可让图片接收的BitmapImage类型,代码如下:
  


    public static class Utils
    {
        public static BitmapImage GetImage(string filename)
        {
            string imgLocation = Application.Current.Resources["ImagesLocation"].ToString();
            StreamResourceInfo imageResource = Application.GetResourceStream(new Uri(imgLocation + filename, UriKind.Relative));
            BitmapImage image = new BitmapImage();
            image.SetSource(imageResource.Stream);
            return image;
        }
         
  
  完成了上述两个类,打开图片对应的Xaml,我这里的名称路径在:/Views/PicturesView/Default.xaml。在该页面的ContentPanel中加入一个DataList 控件,并为其数据模板添加内容显示窗器,比如本例以横向显示的StackPanel中放置了一个图片控件和一个文本控件用来显示图片和图片名称,XML代码如下:
  



            
               
                    
               
               
                    
                        
                           
                                
                                
                           
                        
                    
               
            
          
  
  做Asp.net 的朋友赶快过来围观,这个DataList 数据绑定的方法不是就是ASP.NET常用的写法吗?只是来源做了处理使用Silverlight 的写法,不过看样子和格式都与Asp.Net 的DataList 数据绑定很相似。好了,之后进入CS文件,引用这一命名空间:
  


using System.Collections.Specialized;  
  
  声明上述提到的ObservableCollection对象,将Photo对象放进去,我在做Android 的时候喜欢写数据源的时候这样写:List list=new ArrayList();  然后去自定义一个数据源,感觉灵活性比较强,WP7还没试过,就先暂时使用这种数据对象来实现数据的更新显示吧。
  定义好后,为集合中的PHOTO对象存值和设置DataList的事件并与删除按钮交互,所有代码如下:
  


///
        /// 此事件定义了当数据改变时通知集合触发事件
        ///
       // public event NotifyCollectionChangedEventHandler CollectionChanged;

        ObservableCollection photos = new ObservableCollection();
        private void initializePhotos()
        {
            photos.Add(new Photo() {
                Filename="Butterfly.jpg",
                Image=Utils.GetImage("Butterfly.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Chrysanthemum.jpg ",
                Image = Utils.GetImage("Chrysanthemum.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Desert.jpg",
                Image = Utils.GetImage("Desert.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Field.jpg",
                Image = Utils.GetImage("Field.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Tulips.jpg",
                Image = Utils.GetImage("Tulips.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Flower.jpg",
                Image = Utils.GetImage("Flower.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Hydrangeas.jpg ",
                Image = Utils.GetImage("Hydrangeas.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Butterfly.jpg",
                Image = Utils.GetImage("Butterfly.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Jellyfish.jpg",
                Image = Utils.GetImage("Jellyfish.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Koala.jpg",
                Image = Utils.GetImage("Koala.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Leaves.jpg",
                Image = Utils.GetImage("Leaves.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Lighthouse.jpg",
                Image = Utils.GetImage("Lighthouse.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Penguins.jpg",
                Image = Utils.GetImage("Penguins.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Rocks.jpg",
                Image = Utils.GetImage("Rocks.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Tulip.jpg",
                Image = Utils.GetImage("Tulip.jpg")
            });
            photos.Add(new Photo()
            {
                Filename = "Window.jpg",
                Image = Utils.GetImage("Window.jpg")
            });
        }
        public Default()
        {
            InitializeComponent();
            initializePhotos();
            lstPictures.ItemsSource = photos;
        }
        private void btnRemoveSelection_Click(object sender, RoutedEventArgs e)
        {
            if (null!=lstPictures.SelectedItem)
            {
                photos.Remove(lstPictures.SelectedItem as Photo);
            }
        }
        private void lstPictures_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (null != lstPictures.SelectedItem)
            {
                btnRemoveSelection.IsEnabled = true;
            }
            if (photos.Count==0)
            {
                btnRemoveSelection.IsEnabled = false;
            }
        }  
  
2.应用程序栏
  在很多情况下我们会需要提供跨应用程序的通用功能。一些情况下,我们可能想要为页面提供一些符合某些条件时才出现的特殊功能。另外一些情况下,您只希望获得更多的屏幕空间,这些情况下,Windows Phone 提供了应用程序栏。
  要为应用程序添加应用程序栏,需要在App.xaml 注册。本篇学习的内容注册一个菜单和两个 按钮,一个菜单导航到About 页面,另外一个按钮跳转到Image列表。打开App.xaml,在Application.Resouces节点内,输如下代码并为其添加事件响应:
  


  
        
            
            
               
            
            
            
            
               
               
            
          
  进入APP.xaml.cs在自动生成的事件句柄内,键入如下代码实现跳转:
  


private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
        {
            PhoneApplicationFrame root = Application.Current.RootVisual as PhoneApplicationFrame;
            root.Navigate(new Uri("/About", UriKind.Relative));
        }
        private void ApplicationBarIconButton_Click(object sender, EventArgs e)
        {
        }
        private void ImageEvent_Click(object sender, EventArgs e)
        {
            PhoneApplicationFrame root = Application.Current.RootVisual as PhoneApplicationFrame;
            root.Navigate(new Uri("/Pictures",UriKind.Relative));
        }  
  
  在你需要显示应用程序栏的页面的phone:PhoneApplicationPage节点指定ApplicationBar来源,比如本文的指定方式:
  


  
  
  看看截图效果吧:
DSC0003.png
  
  源码比较大,有需要的EMAIL我:terryyhl@gmail.com

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-65189-1-1.html 上篇帖子: Windows Phone 7 定义和使用字典资源(ResourceDictionary) 下篇帖子: Windows Phone 7 利用计时器DispatcherTimer创建时钟
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表