今天我们来分享一个主题:DesignTime Binding设计时绑定。
这一项技术可以使用在所有包括WPF及其衍生出来的技术上,比如Sliverlight,当然也包括UWP
先来说明一下设计时Binding的重要性,如果没有设计时Binding那么每一次改动都需要运行才可查看,还有就是写一个DateTemplate为了看到效果,每次都运行显然不能接受的。
好好好,现在我们就进入正题。
首先呢我们来创建一个UWP工程(不要求一定是UWP),然后创建一个Models的文件夹再向其中添加一个Music类
Music类代码如下
public class Music { public string Id { get; set; } public string Titile { get; set; } public string MusicUrl { get; set; } public string BackgroundUrl { get; set; } public string AlbumUrl { get; set; } public string Reader { get; set; } public string Author { get; set; } }
注意这里属性是public的,否则无法Binding成功
然后我们向工程中添加一个ViewModels文件夹,然后向其中添加一个MainPageViewModel类
MainPageViewModel类代码如下
public class MainPageViewModel { public List<Music> MusicList { get; set; } = new List<Music>(); public MainPageViewModel() { LoadDesignTimeData(); } /// <summary> /// 添加设计时数据 /// </summary> private void LoadDesignTimeData() { Music m1 = new Music(); m1.Id = "1"; m1.AlbumUrl = "Assets/DesignTime/1.jpg"; m1.Titile = "你若懂我,该有多好"; m1.Reader = "冰夏"; Music m2 = new Music(); m2.AlbumUrl = "Assets/DesignTime/2.jpg"; m2.Titile = "让我们面对现实忠于理想"; m2.Reader = "楚霄"; Music m3 = new Music(); m3.AlbumUrl = "Assets/DesignTime/3.jpg"; m3.Titile = "我是你流浪过的一个地方"; m3.Reader = "纱朵"; MusicList.Add(m1); MusicList.Add(m2); MusicList.Add(m3); } }
现在我们需要在工程中的Asset 文件夹中添加DesignTime文件夹,然后添加三张图片
注意:然后我们先生成一下解决方案
然后打开MainPage的前台页面
先添加一条ViewModel的命名空间
xmlns:vm="using:DesignTimeBinding.ViewModels"
然后在添加一个设计时的DataContext
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type=vm:MainPageViewModel}"
注意如果刚才没有先生成解决方案的话,在写上面那两步的时候是没有提示的。
现在我们来为MainPage添加一些代码
<ListView ItemsSource="{Binding MusicList}"> <ListView.ItemTemplate> <DataTemplate> <Grid Height="50" Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition Width="60"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border Width="50" CornerRadius="4"> <Border.Background> <ImageBrush ImageSource="{Binding AlbumUrl}"/> </Border.Background> </Border> <Grid Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding Titile}"></TextBlock> <TextBlock Grid.Row="1" Text="{Binding Reader}"></TextBlock> </Grid> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView>
生成一下解决方案就会看到如下效果
着过这个时候修改DataTemplate都会实时呈现在XAML设计器中
一个简单的设计时绑定就算完成了。
但是现在会发现ViewModel还有一些问题就是如何在运行时不加载设计时的数据,这个时候就需要做一个判断。
现在就需要知道如何判断当前环境为运行时,现在我能想到的有三个解决方案。有更好的请一定要回复我( ̄_ ̄ ) 先谢过了
1.使用全集变量,在App启动时设置为false,默认为true。
2.使用微软的API
3.MVVM Light
好的先来看一下第一种的实现方法
先在App的后台文件中添加一个属性
public static bool IsInDesignTime { get; set; } = true;
然后在OnLaunched方法中置为false
此时我们修改ViewModel的构造函数
public MainPageViewModel() { if (App.IsInDesignTime) LoadDesignTimeData(); else { // 运行时加载真实数据 } }
然后我看一下第二种方案,微软提供的API
代码如下
public MainPageViewModel() { if (DesignMode.DesignModeEnabled) LoadDesignTimeData(); else { // 运行时加载真实数据 } }
需要注意的是DesignMode.DesignModeEnabled只是UWP上的,Windows Phone 8.0并不一样。所推荐使用第一种,具体的请参见下表
UWP, Windows Store App | DesignMode.DesignModeEnabled |
Sliverlight, Windows Phone | DesignerProperties.IsInDesignTool |
关于第三种方式MVVM Light
属性是ViewModelBase.IsInDesignModeStatic
实现方式应该是封装了微软的API,具体我也不清楚。当然我们也可以编写自己的ViewModelBase
最后再来看一下XAML设计器的强大功能。
刚才的演示中我们把资源文件放到了本地,其实完全可以使用远程的资源。为了手懒我们先安装一个Json.NET的包
然后在MainPageViewModel类中加入这个函数,并调用
private void LoadFromJson() { #region DataSource string dataSource = @"{ 'Data': [ { 'Id': '1035', 'Title': '写给岁月的感谢信', 'Reader': '阡语陌路', 'Author': '六六', 'BackgroundUrl': 'http://cdn.cdut.zhuimeng.me/Voice/Music/d481c88b-ee32-4b16-8fbb-8b8e6113255a.jpg', 'CoverUrl': 'http://cdn.cdut.zhuimeng.me/Voice/Music/c61536c0-345b-4129-860d-58d642e2de79.jpg' }, { 'Id': '1034', 'Title': '几米·星空', 'Reader': '纱朵', 'Author': '几米', 'BackgroundUrl': 'http://cdn.cdut.zhuimeng.me/Voice/Music/0e614225-d1ab-4c75-9d8c-3e99a4c72004.jpg', 'CoverUrl': 'http://cdn.cdut.zhuimeng.me/Voice/Music/725696cb-5feb-491d-85d8-5b76d014b9e2.jpg' }, { 'Id': '1033', 'Title': '女人是男人品味的终极体现', 'Reader': '阿雯', 'Author': '佚名', 'BackgroundUrl': 'http://cdn.cdut.zhuimeng.me/Voice/Music/9ae9a987-6406-4e19-acd0-28e2d2a8b6ef.jpg', 'CoverUrl': 'http://cdn.cdut.zhuimeng.me/Voice/Music/5595d565-5932-47f4-980b-d309e32a4621.jpg' } ], 'Count': 3 } "; #endregion JObject json = JObject.Parse(dataSource); foreach (var item in json["Data"]) { var m = new Music() { Id = item["Id"].ToString(), Titile = item["Title"].ToString(), BackgroundUrl = item["BackgroundUrl"].ToString(), AlbumUrl = item["CoverUrl"].ToString(), Author = item["Author"].ToString(), Reader = item["Reader"].ToString() }; MusicList.Add(m); } }
生成解决方案然后会发现
XAML设计器成功的从远程服务器上获取到了资源!!!
当然了至于到底选用哪一种,还要看各位的选择。
好滴,关于设计时Binding就聊到这里。
如果讲的有什么不足的地方请给我回复!