接着上一篇开发日志继续探讨。
上一篇日志讲到在一个PhonePage里绑定一个数据集,用的是如下的方法:
d:DataContext="{d:DesignData TestDataViewModel.xaml}"
一个xmal文件表示一个数据集,在上面代码里的d:DataContenxt里研究了半天,实在没有办法让一个DataContenxt绑定第二个xaml的数据集,玩过Linq的人都知道,一个DataContenxt下面却可以定义多个集合的,接下来的思路就是怎么在一个xmal里加入两个数据集。
自己设计了两个除了类名外其他都一样的数据类(TestDataItem.cs及TestDataItem2.cs),如下图的文件目录所示,为了显示方便将其放到两个不同的文件夹里,这时就要注意namespace的问题啦。
上面的TestDataCollection.cs、TestDataCollection2、TestDataViewModel.xaml、TestDataViewModel2.xaml是个人作单独显示时用的,想将两个数据集放到同一个DataContext里不需要动用这几个文件。而TotalTestDataCollection.cs是关键的所在,在此定义了一个含有两个数据集合的大集合,其代码如下所示:
//TotalTestDataCollection.cs
using MvTest.TestDataViewModel1;
using MvTest.TestDataViewModel2;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MvcTest.TotalDataViewModel
{
public class TotalTestDataCollection : INotifyPropertyChanged
{
/// <summary>
/// 数据集合1
/// </summary>
public ObservableCollection<TestDataItem> TestDataItems1 { get; private set; }
/// <summary>
/// 数据集合2
/// </summary>
public ObservableCollection<TestDataItem2> TestDataItems2 { get; private set; }
/// <summary>
/// 属性更改事件回调
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 构造函数
/// </summary>
public TotalTestDataCollection()
{
this.TestDataItems1 = new ObservableCollection<TestDataItem>();
this.TestDataItems2 = new ObservableCollection<TestDataItem2>();
}
/// <summary>
/// INotifyPropertyChanged接口的实现
/// </summary>
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
如前一篇笔记强调的,要想让VS认出你的ViewModel,必须要继承INotifyPropertyChanged的接口。然后再新建一个xaml来设计两个数据集的例子(方法见上一篇博文吧),其代码如下所示:
//TotalDataViewModel.xaml
<!-- 这对应的是数据集的类名,表示一组数据-->
<vm:TotalTestDataCollection
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MvcTest.TotalDataViewModel"
xmlns:c1="clr-namespace:MvTest.TestDataViewModel1"
xmlns:c2="clr-namespace:MvTest.TestDataViewModel2">
<!--clr-namespace:MvcTest这是数据集的命名空间,带文件夹的要注意啦-->
<vm:TotalTestDataCollection.TestDataItems1>
<c1:TestDataItem Index="0" Name="name0" Flag="True"></c1:TestDataItem>
<c1:TestDataItem Index="1" Name="name1" Flag="True"></c1:TestDataItem>
<c1:TestDataItem Index="2" Name="name2" Flag="True"></c1:TestDataItem>
</vm:TotalTestDataCollection.TestDataItems1>
<vm:TotalTestDataCollection.TestDataItems2>
<c2:TestDataItem2 Index="3" Name="name3" Flag="True"></c2:TestDataItem2>
<c2:TestDataItem2 Index="4" Name="name4" Flag="True"></c2:TestDataItem2>
<c2:TestDataItem2 Index="5" Name="name5" Flag="True"></c2:TestDataItem2>
</vm:TotalTestDataCollection.TestDataItems2>
</vm:TotalTestDataCollection>
注意代码里的c1、c2的命名空间,否则会无法识别TestDataItem,当然,省事的方法就是将所有的文件放到一个目录下面,好吧,个人是有强迫症的。就这样将两个数据集拼在一个xaml里面了,下面就是在MainPage里呈现出这些数据,为此我设计了两个LongListSelector,分别显示不同的数据,为了区分起见,我设计了两个DataItemTemplate,如下面代码所示:
//MainPage.xaml
<phone:PhoneApplicationPage
x:Class="MvcTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DataContext="{d:DesignData TotalDataViewModel/TotalDataViewModel.xaml}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--单条数据显示的样式-->
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="TestDataItemTemplate">
<StackPanel Margin="0,0,0,0">
<TextBlock Text="{Binding Index}"/>
<TextBlock Text="{Binding Name}" />
<!--TextBlock Text="{Binding Flag}" /-->
<StackPanel Height="1" Background="AliceBlue"></StackPanel>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="TestDataItemTemplate2">
<StackPanel Margin="0,0,0,0">
<TextBlock Foreground="Red" Text="{Binding Index}"/>
<TextBlock Foreground="Yellow" Text="{Binding Name}" />
<TextBlock Foreground="Green" Text="{Binding Flag}" />
<StackPanel Height="1" Background="RoyalBlue"></StackPanel>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="页面名称" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<!--用一个LongListSelector来显示数据集-->
<StackPanel>
<phone:LongListSelector Margin="0,0,0,0" ItemTemplate="{StaticResource ResourceKey=TestDataItemTemplate}" ItemsSource="{Binding TestDataItems1}"/>
<phone:LongListSelector Margin="0,0,0,0" ItemTemplate="{StaticResource ResourceKey=TestDataItemTemplate2}" ItemsSource="{Binding TestDataItems2}"/>
</StackPanel>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
只要d:DataContext关联到TotalDataViewModel.xaml里,编译器倒可以自动感知内容,只要在LongListSelector里绑定好指定的数据集就可以啦,其显示效果如下图所示:
最后总结一下,(1)先设计好你要显示的数据类(TestDataItem.cs);(2)设计好数据集的集合类(TotalTestDataCollection.cs);(3)设计好数据集的内容(TestDataViewModel.xaml);(4)在PhonePage里呈现你的数据。步骤不多,四步而已,虽说如此,但要弄出这个效果可是花了我一个下午的时间,我真是Low爆啦。
末啦,同样附上工程例子,for vs2013。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。