zoukankan      html  css  js  c++  java
  • WP7开发迷你框架G.Controls 介绍

    很久没有写博客了,今天我给大家介绍一个我自己写的一个WP7开发框架G.Controls,首先我将罗列下目前WP7开发遇到的问题。

    1.页面之间如何传递复杂的对象?

    2.从当前页面返回前一页时如何将当前页的某些数据传递给前一页?

    3.如何使得ListBox拥有分页功能?如何使得ListBox中数据在墓碑后自动回复到原来的数据?如何使得ListBox在墓碑后恢复到墓碑前滑动到的项?

    4.如何截获附加属性的值的变化

    5.如何获取某个UIElement所有子孙控件?在ScrollView滚动的时候如何获取屏幕最上边的控件?

    以上种种问题在使用了本框架之后将得到很容易的解决,本人在设计的时候尽量的使得用最少的代码就可以实现以上功能,所以只要使用了本框架,那么你只需写很少的代码就能实现以上的功能。极大的提高开发一个复杂的应用程序的效率,我已经使用该框架开发了多个程序,包括一个电子商务的WP7软件,本人目前使用该框架开发的新浪微博客户端也是使用的该框架,单纯在列表的滑动流畅度方面绝对比新浪官方的流畅,欢迎大家试用。由于已经很长时间没有维护了,所以目前该微博程序还是有不少的Bug,还处于半成品状态,如有问题请直接在设置中给我发送邮件,谢谢!

    新浪微博下载

    如果要使用以上的功能,必须确保当前的页面是继承自GBasePage,添加命名空间: xmlns:gNavigate="clr-namespace:G.Navigate;assembly=G.Controls",然后将PhoneApplicationPage节点改成gNavigate:GBasePage。

    我将使用新浪微博的数据来演示。

    先添加两个类:Message和UserInfo

    下面是Message的类

     public class Message 
    {
    [XmlElement("created_at")]
    public string CreatedTime { get; set; }

    [XmlElement("id")]
    public string Id { get; set; }

    [XmlElement("text")]
    public string Text { get; set; }

    [XmlElement("thumbnail_pic")]
    public string Thumbnail_pic { get; set; }

    [XmlElement("bmiddle_pic")]
    public string Bmiddle_pic { get; set; }

    [XmlElement("original_pic")]
    public string Original_pic { get; set; }

    [XmlElement("user")]
    public UserInfo User { get; set; }

    [XmlElement("source")]
    public Source Source { get; set; }


    [XmlElement("retweeted_status")]
    public Message Retweeted { get; set; }

    private Count count;
    public Count Count
    {
    get
    {
    return count;
    }
    set
    {
    if (count != value)
    {
    count = value;
    }
    }
    }

    }
    public class Count
    {
    [XmlElement("id")]
    public string ID { get; set; }

    [XmlElement("comments")]
    public int Comments { get; set; }

    [XmlElement("rt")]
    public int Rt { get; set; }
    }
    public class Source
    {
    [XmlElement("a")]
    public string Name { get; set; }
    }

    以下是UserInfo的类:

       public class UserInfo
    {
    [XmlElement("name")]
    public string NickName
    {
    get;
    set;
    }

    [XmlElement("screen_name")]
    public string ScreenName
    {
    get;
    set;
    }

    [XmlElement("id")]
    public string Id
    {
    get;
    set;
    }

    [XmlElement("description")]
    public string Description
    {
    get;
    set;
    }

    [XmlElement("gender")]
    public string Gender
    {
    get;
    set;
    }

    [XmlElement("profile_image_url")]
    public string HeadImage
    {
    get;
    set;
    }

    [XmlElement("province")]
    public string Province
    {
    get;
    set;
    }

    [XmlElement("city")]
    public string City
    {
    get;
    set;
    }

    [XmlElement("location")]
    public string Location
    {
    get;
    set;
    }
    /// <summary>
    /// 博客地址
    /// </summary>
    [XmlElement("url")]
    public string Url
    {
    get;
    set;
    }

    /// <summary>
    /// 微博数
    /// </summary>
    [XmlElement("statuses_count")]
    public string StatusesCount
    {
    get;
    set;
    }

    /// <summary>
    /// 关注数
    /// </summary>
    [XmlElement("friends_count")]
    public string FriendsCount
    {
    get;
    set;
    }

    /// <summary>
    /// 粉丝数
    /// </summary>
    [XmlElement("followers_count")]
    public string FollowersCount
    {
    get;
    set;
    }

    [XmlElement("following")]
    public bool Following
    {
    get;
    set;
    }


    [XmlElement("verified")]
    public bool verified
    {
    get;
    set;
    }

    [XmlElement("status")]
    public Message Message
    {
    get;
    set;
    }

    public string MaxHeadImag
    {
    get
    {
    return this.HeadImage.Replace("/50/", "/180/");
    }
    }
    }

    这里使用PageListBox来展示数据,添加命名空间:     xmlns:gControls="clr-namespace:G.Controls;assembly=G.Controls"

    然后使用PageListBox来展示数据:

    <gControls:PageListBox x:Name="listbox"
    SelectionChanged
    ="listbox_SelectionChanged"
    BeginLoadData
    ="listbox_BeginLoadData">
    <gControls:PageListBox.ItemTemplate>
    <DataTemplate>
    <Border toolkit:TiltEffect.IsTiltEnabled="True"
    BorderBrush
    ="{StaticResource PhoneBorderBrush}"
    BorderThickness
    ="0,1,0,1"
    Margin
    ="0,0,0,10"
    CornerRadius
    ="5">
    <StackPanel Margin="5">
    <Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <gControls:TextButton Foreground="{StaticResource PhoneAccentBrush}"
    Text
    ="{Binding User.NickName}"
    FontSize
    ="22"
    HorizontalAlignment
    ="Left"
    x:Name
    ="btnNickName" />
    <TextBlock Text="{Binding Source.Name}"
    Grid.Column
    ="1"
    HorizontalAlignment
    ="Right"
    Foreground
    ="{StaticResource PhoneAccentBrush}" />
    </Grid>

    <TextBlock Text="{Binding Text}"
    FontSize
    ="18"
    TextWrapping
    ="Wrap" />

    <gControls:ImageButton ImageSource="{Binding Thumbnail_pic}"
    Tag
    ="{Binding Original_pic}"
    Click
    ="ImageButton_Click"
    HorizontalAlignment
    ="Center">
    </gControls:ImageButton>
    </StackPanel>
    </Border>
    </DataTemplate>
    </gControls:PageListBox.ItemTemplate>
    </gControls:PageListBox>

    然后在cs代码中插入以下代码:

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
    base.OnNavigatedTo(e);
    this.listbox.EnableTombstoneListBox<Message>(this);
    }

    上面这段代码是每当导航到当前页的时候就启用墓碑功能,这样,当墓碑后PageListBox会自动到恢复原来的数据。

            private void listbox_BeginLoadData(object sender, G.Controls.PageEventArgs e)
    {
    System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };
    timer.Tick += (a, b) =>
    {
    XmlAttributes rootAttrs = new XmlAttributes();
    rootAttrs.XmlRoot = new XmlRootAttribute("statuses");
    XmlAttributeOverrides attrOvrs = new XmlAttributeOverrides();
    attrOvrs.Add(typeof(GetMessagesResponse), rootAttrs);
    System.Xml.Serialization.XmlSerializer se = new System.Xml.Serialization.XmlSerializer(typeof(GetMessagesResponse), attrOvrs);
    GetMessagesResponse response = se.Deserialize(Application.GetResourceStream(new Uri("/PhoneApp2;component/weibo.xml", UriKind.Relative)).Stream) as GetMessagesResponse;
    this.listbox.LoadData<Message>(response.Messages);
    this.ShowState(string.Format("当前页{0},每页{1}条数据", e.PageNum, e.PageSize));
    timer.Stop();
    };
    timer.Start();
    }


    以上代码是模拟从服务端获取数据,并且将XML数据转换成相对应的类,使用    this.listbox.LoadData<Message>(response.Messages);添加数据,this.ShowState(string.Format("当前页{0},每页{1}条数据", e.PageNum, e.PageSize));方法将会以一个黄条状的提示信息在屏幕最上那边提示信息。

    以上工作以后,PageListBox就已经拥有了分页、墓碑、墓碑后自动滑动到墓碑前项的功能。

    以下演示页面间数据的传递功能,就是将一个Message对象传递给下一页。

        private void listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    if (listbox.SelectedItem != null)
    {
    Message message = listbox.SelectedItem as Message;
    this.NavigationService.Navigate("/Page1.xaml", message);
    this.listbox.SelectedItem = null;
    }
    }

    以上代码的核心是    this.NavigationService.Navigate("/Page1.xaml", message);这个方法将会将message传递给下一页。

    在下一页中如何取数据?

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
    base.OnNavigatedTo(e);
    Message message = this.NavigationContext.Param as Message;
    this.ContentPanel.DataContext = message;
    }

    以上代码的核心就是this.NavigationContext.Param ,Param 就是前一页传递过来的参数,是要该参数能够被序列化,那么就不用担心墓碑后丢失的问题,因为我已经处理过了。

    下面演示如何将当前页的数据传递给前一页:加入当前页有一个TextBox,当我返回到前一页的时候需要将TextBox的值传递给前一页,

    首先在当前页添加TextBox和一个按钮

                <StackPanel Orientation="Horizontal"
    Grid.Row
    ="2">
    <TextBox Width="300"
    x:Name
    ="txt" />
    <Button Content="返回"
    Click
    ="Button_Click" />
    </StackPanel>

    然后在当前页的cs后台代码中插入以下代码:

         protected override void OnNavigatingFromBack(NavigateBackFromEventArgs e)
    {
    base.OnNavigatingFromBack(e);
    e.HasHandle = true;
    e.Param = txt.Text;
    }

    注意,必须将HasHandle设置为True,否则返回的时候接收不到数据的!

    然后在前一页添加以下代码:

           protected override void OnNavigatingBackFrom(NavigateBackFromEventArgs e)
    {
    base.OnNavigatingBackFrom(e);
    MessageBox.Show(e.Param as string);
    }

    以上就实现了从当前页返回前一页传递数据的功能。



     现在演示如何截获ScrollView的VerticalOffset属性值的更改:

    首先在页面中添加一个ScrollView,然后在后台代码或者直接在XAML插入代码,下面演示使用后台代码的方式实现:

    G.PropertyValueChangedNotify.Create("VerticalOffset", scrollView).PropertyValueChanged += new G.PropertyValueChangedHandle(ScrollView_PropertyValueChanged);
     

    使用上面的代码注册VerticalOffset属性更改后的事件通知

       void ScrollView_PropertyValueChanged(DependencyObject d, G.PropertyValueChangedEventArgs e)
    {
    txtScroll.Text = e.NewValue.ToString();
    }

    以上代码就可以将ScrollView的当前VerticalOffset的属性值截获。

    以下演示框架中的一个ChildWindow控件:当我点击微博的某张图片的时候,需要查看大图,这时候就需要使用ChildWindow来实现该功能了。

    添加一个XAML文件,代码如下:

    <childWindow:ChildWindow x:Class="PhoneApp2.BrowserImageChildWindow"
    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"
    xmlns:childWindow
    ="clr-namespace:G.Controls;assembly=G.Controls"
    FontFamily
    ="{StaticResource PhoneFontFamilyNormal}"
    FontSize
    ="{StaticResource PhoneFontSizeNormal}"
    Foreground
    ="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight
    ="480"
    d:DesignWidth
    ="480">

    <Grid x:Name="LayoutRoot" Background="Black">
    <Image Source="{Binding}" />
    </Grid>
    </childWindow:ChildWindow>

    修改后台代码

    public BrowserImageChildWindow(string url)
    {
    InitializeComponent();
    this.LayoutRoot.DataContext = url;
    }

    然后当单击图片的时候浏览大图:

           private void ImageButton_Click(object sender, RoutedEventArgs e)
    {
    ImageButton btn = sender as ImageButton;
    BrowserImageChildWindow windows = new BrowserImageChildWindow(btn.Tag as string);
    windows.Show();
    }

    框架中还有其他很多的功能,如果大家有兴趣的话可以自己研究下该框架。

    后面我会写一篇博客专门讨论如何提升WP7程序性能的文章,相信各位都曾被WP7的性能问题困扰吧?

    以下贴出Demo源码下载链接:

     点击下载

    以上源码只是demo的源码,并未贴出框架的源码。如果需要的可以向我索取源码,如果索要的人多的话我会直接把源码发出来的,嘿嘿!

    未经本人允许,不得私自使用本框架进行商业行为!

  • 相关阅读:
    bk.
    仅仅为了记录
    一个简单的Lua解释器
    Lua与C++相互调用
    Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作用
    OGNL表达式struts2标签“%,#,$”
    Java异常报错机制
    到底EJB是什么?
    Spring总结
    JSON(JavaScript Object Notation)
  • 原文地址:https://www.cnblogs.com/dagehaoshuang/p/2192082.html
Copyright © 2011-2022 走看看