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

Windows 8 Metro 开发疑难杂症(二)——不规则宫格布局以及不同Item对应不同模版

[复制链接]

尚未签到

发表于 2015-5-22 10:47:05 | 显示全部楼层 |阅读模式
  我先介绍下win8里面带有的列表控件:


  • ItemsControl  ItemsControl  是所有列表控件的基类,实际使用过程中不常用。
  • ListBox listbox控件在win8里面的地位已经下降了很多(在WP中Listbox是最常用的列表控件),也是属于不常用控件。
  • ListView listview控件的地位相当于WP中的listbox,是用来做垂直列表或水平列表最好控件,不支持宫格列表。
  • GridView  gridview是专门用来做宫格布局的,不能用来做垂直或水平列表控件(虽然可以用StackPanel面板,但是不能滑动的)。
  • FlipView flipview控件界面上一次只能呈现一个item,主要用来做图片浏览用的。

下面说正事。

  不知道大家有没有注意过Win8自带的商店的宫格的布局以及metro界面下桌面的宫格布局?这两种布局方式每一格的占用大小是不一样的。但是在win8自带的控件中没有这样的控件,虽然有gridview控件,但是gridview本身不支持不规则(下面提到的不规则指的是每一个宫格占用的空间不一致)宫格布局,但是gridview 支持VariableSizedWrapGrid,而VariableSizedWrapGrid是支持不规则宫格布局的,这样我们就可以自定义一个控件来实现以上的功能。
  下面新建一个网格应用程序项目。直接运行程序会看到首页的布局是宫格的布局,但是每一格的大小是一样的(如下图)。 DSC0000.png
  下面我们需要自定义一个控件来实现不规则宫格布局,叫做VariableSizedGridView控件,继承自GridView



  public class VariableSizedGridView : GridView
{
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
IGridItemSize gridItemSize = item as IGridItemSize;
ContentControl gridViewItem = element as ContentControl;
if (gridItemSize != null)
{
//设置元素占用的列数和行数
                VariableSizedWrapGrid.SetColumnSpan(gridViewItem, gridItemSize.ColSpan);
VariableSizedWrapGrid.SetRowSpan(gridViewItem, gridItemSize.RowSpan);
}
base.PrepareContainerForItemOverride(element, item);
}
}
  还有定义一个接口用来实现宫格所占的列数和行数,新建类IGridItemSize,代码如下:



public interface IGridItemSize
{
//占用列的数量
int ColSpan { get; set; }
//占用行的数量
int RowSpan { get; set; }
}
  为了能实现不规在布局,还要给数据源的Item继承IGridItemSize接口,这样才能让VariableSizedGridView控件实现不规在布局。
修改SampleDataSource文件下的SampleDataItem类,让SampleDataItem继承IGridItemSize接口,在SampleDataItem构造函数里面添加如下代码。然后在类SampleDataSource的构造函数里给SampleDataItem的ColSpan或RowSpan属性赋值。
  现在我们需要修改GroupedItemsPage的XAML代码,如下:



     








































  这样就可以直接运行,看到效果了,如下图:
DSC0001.png
  
  到此我得提醒下各位,由于宫格的每行的高度和每列的宽度是固定,那也就是说我们需要提前计算好不规则宫格所占用的列数和行数,以便达到最佳的布局。
  到这里我们可能会想,既然每一格占用的列数和行数是不一定的,那是否可以对每一格的模版进行差异化设置呢?如下图效果:
DSC0002.png
  
  答案是肯定的。这里依然需要对我们的自定义控件进行改造。
  首先我们需要一个DataTemplat集合,用来存放不同的宫格对应的模版,然后我们需要一个附加属性,对DataTemplate设置一个Tag值用来标记模版,这样在初始化Item的时候能找到正确的模版。我们还需要给IGridItemSize添加一个类型为Int的属性Tag。



public class VariableSizedGridView : GridView
{
public VariableSizedGridView()
{
this.DataTypes = new List();
}
public static readonly DependencyProperty DataTemplateDataTagProperty = DependencyProperty.RegisterAttached("DataTemplateDataTag", typeof(int), typeof(VariableSizedGridView), new PropertyMetadata(0));
public static int GetDataTemplateDataTag(DataTemplate element)
{
return (int)element.GetValue(VariableSizedGridView.DataTemplateDataTagProperty);
}
public static void SetDataTemplateDataTag(DataTemplate element, int value)
{
element.SetValue(VariableSizedGridView.DataTemplateDataTagProperty, value);
}
public static readonly DependencyProperty DataTypesProperty = DependencyProperty.Register("DataTypes", typeof(List), typeof(VariableSizedGridView), null);
public List DataTypes
{
get
{
return this.GetValue(VariableSizedGridView.DataTypesProperty) as List;
}
set
{
this.SetValue(VariableSizedGridView.DataTypesProperty, value);
}
}
protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
{
IGridItemSize gridItemSize = item as IGridItemSize;
ContentControl gridViewItem = element as ContentControl;
if (gridItemSize != null)
{
//设置元素占用的列数和行数
                VariableSizedWrapGrid.SetColumnSpan(gridViewItem, gridItemSize.ColSpan);
VariableSizedWrapGrid.SetRowSpan(gridViewItem, gridItemSize.RowSpan);
//如果tag不为0,那么表示需要使用默认模板以外的模版
if (gridItemSize.Tag == 0)
{
base.PrepareContainerForItemOverride(element, item);
}
else
{
//获取tag对应的模版
var a = this.DataTypes.FirstOrDefault(c => VariableSizedGridView.GetDataTemplateDataTag(c) == gridItemSize.Tag);
if (a == null)
{
base.PrepareContainerForItemOverride(element, item);
}
else
{
base.PrepareContainerForItemOverride(element, item);
//将模版赋值给gridViewItem
gridViewItem.ContentTemplate = a;
}
}
}
else
base.PrepareContainerForItemOverride(element, item);
}
}
  到这控件的实现逻辑已经写完了,下面就是在实际的使用。
  首先还是修改数据源的Tag值,让不同的item对应不同的模版。修改SampleDataSource文件下的代码。
  下面再修改下GroupedItemsPage的XAML代码



   






























































  到这,目标达到了,即实现了不规这宫格布局,还实现了不同的宫格对应不同的模版。
源代码下载

运维网声明 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-69503-1-1.html 上篇帖子: 企业部署Windows 8 Store 风格应用 下篇帖子: Windows 8 应用商店应用开发 之 图形绘制(2)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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