随笔 - 55  文章 - 15  trackbacks - 0
<2013年1月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

       
      前情提要:若要实现一个类似于Windows Store的界面的话,这个类必须要先继承自GridView,并且要重写PrepareContainerForItemOverride方法。微软提供的模板中又给出了两个依赖属性来帮助我们完成这种可变尺寸的GridView。下面我们来看看重载的PrepareContainerForItemOverride方法都做了些什么。

       首先来看微软官方给出的该方法的描述:
       Prepares the specified element to display the specified item.
      用特定的元素来显示特定的项。

怎么理解?看代码理解:
1 protected:
2 virtual void PrepareContainerForItemOverride(
3   DependencyObject^ element, 
4   Object^ item
5 )
6 

element: The element that's used to display the specified item.
item: The item to display.
即,用此element来表现该item,继而显示这个item。一般情况下,我们的GridView里面都会有N个Item,那么,该方法会执行N遍,使每个Item都能被设定。即我们的GridView就是Container:
 1 void VariableGridView::PrepareContainerForItemOverride(DependencyObject^ element, Platform::Object^ item)
 2 {
 3     GridView::PrepareContainerForItemOverride(element, item);
 4     auto viewMode = (Data::DataItem^)(item);
 5     UIElement^ uiElement = safe_cast<UIElement^>(element);
 6 
 7     Binding^ colBinding = ref new Binding();
 8     colBinding->Source = viewMode;
 9     colBinding->Path = ref new PropertyPath(this->ItemColSpanPropertyPath);
10     BindingOperations::SetBinding(uiElement,VariableSizedWrapGrid::ColumnSpanProperty, colBinding);
11     
12 
13     Binding^ rowBinding = ref new Binding();
14     rowBinding->Source = viewMode;
15     rowBinding->Path = ref new PropertyPath(this->ItemRowSpanPropertyPath);
16     BindingOperations::SetBinding(uiElement,VariableSizedWrapGrid::RowSpanProperty, rowBinding);    
17 }
第3行: 先调用父类方法进行基础操作(具体不清楚做什么,但是这一步必须要有,可以放在最前,也可以放在最后)。

第4行: 要显示的Item。 我们的Item都是Data::DataItem类型的,所以要进行类型转换。这里注意,WinRT中所有的类都是从Platform::Object^ 继承而来,我们可以用(DataItem^)(item)进行转换,也可以用safe_cast<DataItem^>(item)来进行转换。

第5行: 指定的element。这里转换成UIElement类型。

7--10行:将绑定的source(源)设置为我们的item,绑定的path(路径)设置为VariableSizedGridView的ItemColSpanPropertyPath。这里容易产生混淆:一般情况下,我们在进行数据绑定的时候,path一般是source的一个属性,比如说,一般情况下应该是类似于这样:colBinding->Source = viewMode; colBinding->Path = ref new PropertyPath(viewMode->propertyOfViewMode);  这里竟然设置成了另外一个类的属性,所以之前我迷惑了很长一段时间。但是如果你去XAML文件里面看一下的话,就知道它为什么这么做了。我们先不要着急看XAML文件,还有第10行。

Associates a Binding with a target property on a target object. This method is the code equivalent to declaring a {Binding} in markup.
将目标对象的目标属性进行绑定。
  
1 
2 public:
3 static void SetBinding(
4   DependencyObject^ target, 
5   DependencyProperty^ dp, 
6   BindingBase^ binding
7 )
8 
9 
    
第10行的意思是说:将uiElment的VariableSizedWrapGrid::ColumnSpan属性同该item的itemColSpanPropertyPath进行绑定。但是item没这个属性。现在是时候来看看XAML文件了:

 1  <common:VariableGridView
 2             x:Name="itemGridView"
 3             AutomationProperties.AutomationId="ItemGridView"
 4             AutomationProperties.Name="Grouped Items"
 5             Padding="0"
 6             ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
 7             ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
 8             SelectionMode="None"
 9             IsSwipeEnabled="false"
10             IsItemClickEnabled="True"
11             ItemClick="ItemView_ItemClick"
12             ItemColSpanPropertyPath="ColumnSpan"
13             ItemRowSpanPropertyPath="RowSpan" Grid.Row="2"
14             Margin="30,20,20,10" ItemTemplate="{StaticResource BigDateTemplate}">

我们看到ItemColSpanPropertyPath被赋值成了ColumnSpan,而item中正好有这么个属性:

 1 namespace Data
 2 {
 3 [Windows::UI::Xaml::Bindable]
 4 public ref class DataItem
 5 {
 6 //
 7 //            
 8                         property int RowSpan{ int get(); void set(int);}
 9             property int ColumnSpan{ int get(); void set(int);}
10 //
11 //
12 };
13 }
那么一切都说的过去了,原来绑定的Source是DataItem,path是ColumnSpan。

      那么这个重载的方法的最终目的就相当于是这么一个语句:
1 <common:VariableGridView            VariableSizedWrapGrid.ColumnSpan="{Binding Source={data::DataItem}, Path=ColumnSpan}"/>
即,在初始化DataItem的时候,只要设置了ColumnSpan这个值,就能使这个Item的列进行相应地改变。
      
      其实整个过程非常之简单,我们的目的就只是上面的一个语句而已,为了达到这个目的,我们设置了两个依赖属性来接收字符串,并且重载PrepareContainerForItemOverride方法进行绑定。大家可以通过示例代码进行领会。
      OK,这一篇是补上周六的。尽量做到每天一篇,保质保量。
      下期提示:刚刚看过了微软提供的模板,下一篇讲述我们自己的方法。该方法同微软的方法大同小异,但是,是网上的一位牛人自己写的,他也是用C#写出来,我把它改成C++版本。
posted on 2012-10-14 17:46 Dino-Tech 阅读(1642) 评论(7)  编辑 收藏 引用

FeedBack:
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 15:31 英明神武可爱
auto viewMode = (Data::DataItem^)(item);
这句话里的 DataItem^ 是什么,
我编译一直提示 Data 没有成员 DataItem  回复  更多评论
  
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 15:45 英明神武可爱
你要看到留言,可以加我的QQ:1045330487;,我有问题请教。
这个沟通真是太不方便。 。。。  回复  更多评论
  
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 15:51 Dino-Tech
@英明神武可爱
Hello, DataItem是我自己定义的一个类,在自定义的Data命名空间中。这句话的意思是把一个item转换成我自己的DataItem类型。  回复  更多评论
  
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 16:16 英明神武可爱
你可以加我的qq吗,我按你的方法继承了gridview,但是编译不过。  回复  更多评论
  
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 16:23 英明神武可爱
我现在用GridView 控件生成了界面。现在想用你的方法更改某一个item;
colBinding -> Path = ref new PropertyPath( this -> ItemColSpanPropertyPath);

ItemColSpanPropertyPath 是什么东西?
  回复  更多评论
  
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 17:23 Dino-Tech
@英明神武可爱
额,这样,你可以参考一下C#版本。
打开你的VS2012,打开File->New Project, 点击Online->Templates->Visual C#, 其中有一个Variable Sized Grid Template,里面的代码跟C++的方法是类似的。
我现在不能上qq,晚上加吧。  回复  更多评论
  
# re: Windows 8 学习笔记(四)--创建Variable Sized GridView之PrepareContainerForItemOverride方法 2013-01-08 17:28 英明神武可爱
@Dino-Tech
@Dino-Tech

OK,期待你加我的QQ.
  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理