总结一些以前用过的界面框架,贴出来给新手参考。
先介绍一个用于文章的图文混排,具有列表的格式。
左边为标题,文字内容。下面为一个List结构,包含标题和内容。右边为图片。
1 . Model
整体结构
public class ProductListItem
{
public ProductListItem(string title, string content, List li, PageType frameType, Uri pic)
{
Title = title; //标题
Content = content; //文本内容
Li = li; //列表
FrameType = frameType; //页面标记,定义为enum
Pic = pic; //图片路径
}
public string Title { get; set; }
public string Content { get; set; }
public PageType FrameType { get; set; }
public List Li { get; set; }
public Uri Pic { get; set; }
public ImageSource Is
{
get
{
return new BitmapImage(Pic);
}
}
}
列表结构
public class TitleContent
{
public TitleContent(string title, string content)
{
Title = title;
Content = content;
}
public string Title { get; set; }
public string Content { get; set; }
}
2 . ViewModel
class ProductListViewModel
{
public List SelectedProductItems = new List();
public List _ProductItems = null;
public ProductListViewModel()
{
if (_ProductItems == null)
{
InitProductItems();
}
}
//所有的赋值操作
public void InitProductItems()
{
var resourceLoader = ResourceLoader.GetForCurrentView();
_ProductItems = new List();
List Tc = new List();
Tc.Add(new TitleContent("Universal Windows Application1", "Hello World!"));
Tc.Add(new TitleContent("Universal Windows Application2", string.Empty));
Tc.Add(new TitleContent("Universal Windows Application3", "Good!"));
_ProductItems.Add(new ProductListItem("CSDN Blog", "http://blog.csdn.net/xiahn1a", Tc, PageType.ProductPage1, new Uri("ms-appx:///Assets/rocket.jpg")));
}
//根据页面的标记,选出用于该页面的信息
public void GetSelectedItem(PageType pt)
{
SelectedProductItems = _ProductItems.Where(i => i.FrameType == pt).ToList();
}
}
3.View
xmlns:ValueConverters="using:MyApp.ValueConverters"
定义列表数据模板:
<Page.Resources>
<ValueConverters:StringEmptyToVisibilityConverter x:Key="StringEmptyToVisibilityConverter"/>
<DataTemplate x:Key="MainProductItemTemplate" x:DataType="local:TitleContent">
<StackPanel>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto">ColumnDefinition>
<ColumnDefinition Width="*">ColumnDefinition>
Grid.ColumnDefinitions>
<SymbolIcon Grid.Column="0" Symbol="Accept" Foreground="#FF1ABC9C" />
<TextBlock Grid.Column="1" Text="{x:Bind Title}" Margin="15,5,0,5" FontSize="16" TextWrapping="Wrap"/>
Grid>
<TextBlock Text="{x:Bind Content}" FontSize="16" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" TextWrapping="Wrap" Visibility="{x:Bind Content, Converter={StaticResource StringEmptyToVisibilityConverter}}" Margin="0,0,0,5"/>
StackPanel>
DataTemplate>
Page.Resources>
其中用到的Converter,意义在于设定部分可见性。此处定义为,如果字符串为空,则该部分不可见。这样使得模板在某部分信息缺失时也可用,不会影响排版。Converter定义如下:
namespace MyApp.ValueConverters
{
public class StringEmptyToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null)
return Visibility.Collapsed;
var result = (string)value;
return result.Equals(string.Empty) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
定义左侧文字整体结构:
<Grid x:Name="Grid_Main" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
"0,20,0,0">
"Tb_Title" Text="{Binding Title}" FontSize="20" HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Top" Foreground="#FF1ABC9C" TextWrapping="Wrap" FontWeight="Normal"/>
"Tb_Content" Text="{Binding Content}" FontSize="16" Margin="10,10,10,10" VerticalAlignment="Top" TextWrapping="Wrap" Visibility="{Binding Content, Converter={StaticResource StringEmptyToVisibilityConverter}}"/>
"Lv_Main" ItemTemplate="{StaticResource MainProductItemTemplate}" HorizontalContentAlignment="Stretch" Style="{StaticResource ListViewStyle1}" ItemContainerStyle="{StaticResource TitleItemContainerStyle}" ItemsSource="{Binding Li}" Margin="10,0,10,0"/>
Grid>
其中对ListView的Style进行了修改,主要目的是删减多余的动画效果。代码过长且并不关键,不贴了。
对应的后台cs文件:
public sealed partial class ProductListView : Page
{
public ProductListView()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
DataContext = e.Parameter;
}
}
界面定义时已进行数据绑定,此处只需DataContext = e.Parameter;
赋值即可。
模板的引用方法:
在页面中定义一个Frame,后台代码中只需完成Frame跳转即可。
public sealed partial class ProductPage1 : Page
{
private readonly ProductListViewModel _viewModel;
public ProductPage1()
{
this.InitializeComponent();
_viewModel = new ProductListViewModel(); //viewmodel
_viewModel.GetSelectedItem(PageType.ProductPage1); //选出用于本页使用的部分
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
MainFrame.Navigate(typeof(ProductListView), _viewModel.SelectedProductItems[0]); //跳转页面,传递数据
}
}
如以后需要再使用该模板创建更多的实例,则在ViewModel中赋值,对_ProductItems加入更多信息。以PageType这个标记作为引用时的区分。引用不同数据时只需改PageType这一个参数即可。
已经完成了左边文字部分的模板定义。现在把图片加入进去,并且设置,当窗口过小时,排版规则从文字图片左右排布,变为上下排布。
再定义一个View:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
"1*">
"1*">
Grid.ColumnDefinitions>
<Grid.RowDefinitions>
"1*">
"1*" MinHeight="300">
Grid.RowDefinitions>
<Grid x:Name="Grid1" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Grid.RowSpan="1" Margin="5">
<Frame x:Name="ProductFrame">Frame>
Grid>
<Grid x:Name="Grid2" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1" Margin="5">
<Grid.Background>
"{Binding Is}" Stretch="Uniform"/>
Grid.Background>
Grid>
"{StaticResource LargeWindowSnapPoint}" />
<Setter Target="Grid1.(Grid.Column)" Value="0"/>
<Setter Target="Grid1.(Grid.ColumnSpan)" Value="1"/>
<Setter Target="Grid1.(Grid.Row)" Value="0"/>
<Setter Target="Grid1.(Grid.RowSpan)" Value="2"/>
<Setter Target="Grid2.(Grid.Column)" Value="1"/>
<Setter Target="Grid2.(Grid.ColumnSpan)" Value="1"/>
<Setter Target="Grid2.(Grid.Row)" Value="0"/>
<Setter Target="Grid2.(Grid.RowSpan)" Value="2"/>
Grid>
代码较多,但实际上只是定义了一个触发器。当窗口大小小于某个数值的时候,将Grid1和Grid2的左右排布变为上下排布。Grid1中的Frame即为上面定义的左侧文字部分。
后台代码与定义左侧部分时基本相同,代码如下:
public sealed partial class ProductListFullView : Page
{
public ProductListFullView()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
DataContext = e.Parameter;
ProductFrame.Navigate(typeof(ProductListView), e.Parameter);
}
}
对于模板的修改,减少内容可以定义Visibility,利用Converter对于绑定参数内容,判断是否为空,决定可见性。
可根据实际情况进行修改,此类模板的定义基本大同小异。
代码通过Visual Studio 2017测试。
转载请注明出处。
请不要私信索要代码,代码都是从完整的工程中节选并简化的,写完这个文档以后我也没有留存。