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

Windows Phone, Win 8/WPF, Windows Form 的ItemsControl的ItemTemplate模版和Style风格多样化[自

[复制链接]

尚未签到

发表于 2015-5-22 11:31:34 | 显示全部楼层 |阅读模式
  Vancee@博客园     转载请注明原文链接:http://www.iyunv.com/vancee/archive/2012/11/04/2754081.html
  
  大多数时候,使用ItemsControl及其子类控件的时候,都是使用的相同的ItemTemplate和style, 所有的元素看起来都是一模一样,但是有些时候也需要一些定制,下面这是整理的wpf, windows form, windows phone上的实现方式。
  其中wpf和winform都提供了现成的实现方法,Windows phone需要一些加工才能实现,可以参考Nick Randolph 的实现方法。
  1. Windows8/WPF
  StyleSelector, DataTemplateSelector 和他们的子类, 提供一种将根据自定义逻辑的样式。
  这个很简单,参考MSDN:
  http://msdn.microsoft.com/zh-cn/library/system.windows.controls.styleselector.aspx
  我自己的Win8上的Demo实现的效果图如下:
DSC0000.png
  
  2. Windows Phone
  Windows Phone上没有StyleSelector可以提供自定义逻辑的样式,但是也可以实现,主要就是重写ContentControl的OnContentChanged事件,实现自定义逻辑的DataTemplate或者Style,
  我参考 了Nick Randolph 的文章《Multiple Item Templates in Windows Phone》,实现了效果图如下:
DSC0001.png
  链接: Multiple Item Templates in Windows Phone
  http://visualstudiomagazine.com/articles/2012/08/06/multiple-item-templates-in-windows-phone.aspx
  附上Nick Randolph 的原文如下:
  How to use a template selector to dynamically select which item template to use for each list item.


  • By Nick Randolph
  • 08/06/2012
  Earlier this year we took a look at working with ListBoxes in a Windows Phone application. That article demonstrated how to style items within a Listbox using a single item template, ensuring that all items in the list have the same layout.
  But there are some cases where this isn't the desired behavior. In this article you'll see how to use a template selector to dynamically select which item template to use for each list item.
  From the previous article, we'll reuse the design time data; this is a collection of contacts, each with a Name and an ImageUrl property. The corresponding item template for the Listbox was similar to the following XAML, which has an Image control on the left and a TextBlock on the right.





   1:
   2:     
   3:         
   4:            
   5:            
   6:         
   7:         ;
  10:         ;
  13:     
  14:
In this example, we want to change this so that each alternate contact has the Image on the right side. There are a number of different ways to do this, but for the purpose of this article we're going to use a template selector to switch between two different item templates. The first thing we're going to need is an alternative item template, as in the following XAML:




   1:
   2:     
   3:         
   4:            
   5:            
   6:         
   7:         ;
   9:         ;
  13:     
  14:
  You can see from this XAML that it's virtually the same as the previous XAML, with the exception that the columns have been exchanged, positioning the Image on the right of the TextBlock. You may wonder how we're going to switch between these two templates, since the ListBox control only has a single ItemTemplate property.
  The trick is that we need to add a template selector control, which is going to dynamically pick which item template to use. The template selector actually comes in two parts: The first is a reusable abstract class, which can simply be added to any of your Windows Phone projects:





   1: public abstract class TemplateSelector : ContentControl
   2: {
   3:     public abstract DataTemplate SelectTemplate(object item, DependencyObject container);
   4:
   5:     protected override void OnContentChanged(object oldContent, object newContent)
   6:     {
   7:         base.OnContentChanged(oldContent, newContent);
   8:
   9:         ContentTemplate = SelectTemplate(newContent, this);
  10:     }
  11: }
  Essentially, the TemplateSelector abstract class exposes a SelectTemplate method, which needs to be implemented for the specific scenario within your application. The ContactTemplateSelector, in the following code block, implements the SelectTemplate method in order to return an item template used to display the Listbox item.





   1: public class ContactTemplateSelector : TemplateSelector
   2: {
   3:     public DataTemplate ImageLeft
   4:     {
   5:         get;
   6:         set;
   7:     }
   8:  
   9:     public DataTemplate ImageRight
  10:     {
  11:         get;
  12:         set;
  13:     }
  14:  
  15:  
  16:     public override DataTemplate SelectTemplate(object item, DependencyObject container)
  17:     {
  18:     // Determine which template to return;
  19:     }
  20: }
  In this case, the ContactTemplateSelector has two DataTemplate properties. By exposing these properties it means that the item templates returned by the SelectTemplate method can be designed in Expression Blend, rather than being hard-coded within the ContactTemplateSelector.
  The logic within the SelectTemplate method will vary depending on your application scenario. For this example, we're going to add a bool IsLeft property to the design time data in Expression Blend. Thus the SelectTemplate method uses this property to determine which item template to return.





   1: public override DataTemplate SelectTemplate(object item, DependencyObject container)
   2: {
   3:     var contact = item as ContactsItem;
   4:     if (contact != null)
   5:     {
   6:         return contact.IsLeft ? ImageLeft : ImageRight;
   7:     }
   8:  
   9:     return null;
  10: }
  So far, our XAML has two item templates: ImageOnLeftItemTemplate and ImageOnRightItemTemplate. We need to add a new template which includes the ContactTemplateSelector:





   1:
   2:     ;
   6:
  We then need to update the Listbox to use this new item template:





   1:
  When you run this, your application should look similar to Figure 1.
  
[Click on image for larger view.]

  Figure 1.Alternating item templates.
  An interesting side effect is that in Expression Blend you'll only see one of the two item templates being used. This is due to the way that Expression Blend loads the design time data. In the ContactTemplateSelector, it assumes that a ContactsItem will be passed in, which is true at runtime. However, at design time Expression Blend loads a different type of object (actually it has the same name but isn't the same CLR type).
  To resolve this, you can add a little reflection magic so that you can see at design time the two different item templates. It's important to note that we don't use the reflection logic at runtime, as this can introduce a significant performance hit within your application.





   1: public override DataTemplate SelectTemplate(object item, DependencyObject container)
   2: {
   3: #if DEBUG
   4:     if(DesignerProperties.IsInDesignTool)
   5:     {
   6:         var isLeftProperty = item.GetType().GetProperty("IsLeft");
   7:         if(isLeftProperty!=null)
   8:         {
   9:             var isLeft = (bool) isLeftProperty.GetValue(item, null);
  10:             return isLeft ? ImageLeft : ImageRight;
  11:         }
  12:     }
  13: #endif
  14:  
  15:     var contact = item as ContactsItem;
  16:     if (contact != null)
  17:     {
  18:         return contact.IsLeft ? ImageLeft : ImageRight;
  19:     }
  20:  
  21:     return null;
  22: }
  In this article, you've seen how to dynamically switch between different item templates so as to change the layout of items within a list. This is useful if the layout of your items varies significantly, but can introduce a performance hit for lists which contain a large number of items.
  There are other ways to solve this problem (such as data binding the visibility property of elements in the template to attributes on the data), so it's important to evaluate the most efficient option available for your application.
  
  3. Windows Form窗体
  DrawItem 事件, 在所有者绘制的 ListBox 在视觉外观更改时发生; 也就是说在绘制的时候更新视觉效果,达到ItemsControl的Items不必统一化的外观效果。
  这个也很好实现,参考MSDN:
  http://msdn.microsoft.com/zh-cn/library/system.windows.forms.listbox.drawitem(v=vs.110).aspx





   1: private void ListBox1_DrawItem(object sender,
   2:     System.Windows.Forms.DrawItemEventArgs e)
   3: {
   4:     // Draw the background of the ListBox control for each item.
   5:     e.DrawBackground();
   6:     // Define the default color of the brush as black.
   7:     Brush myBrush = Brushes.Black;
   8:
   9:     // Determine the color of the brush to draw each item based
  10:     // on the index of the item to draw.
  11:     switch (e.Index)
  12:     {
  13:         case 0:
  14:             myBrush = Brushes.Red;
  15:             break;
  16:         case 1:
  17:             myBrush = Brushes.Orange;
  18:             break;
  19:         case 2:
  20:             myBrush = Brushes.Purple;
  21:             break;
  22:     }
  23:  
  24:     // Draw the current item text based on the current Font
  25:     // and the custom brush settings.
  26:     e.Graphics.DrawString(ListBox1.Items[e.Index].ToString(),
  27:         e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
  28:     // If the ListBox has focus, draw a focus rectangle around the selected item.
  29:     e.DrawFocusRectangle();
  30: }
  Vancee@博客园     转载请注明原文链接: http://www.iyunv.com/vancee/archive/2012/11/04/2754081.html

运维网声明 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-69535-1-1.html 上篇帖子: Windows 8 应用商店应用开发 之 响应运动的传感器 下篇帖子: Windows Phone 8 如何在内存与硬件受限的设备上开发
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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