在现代应用程序开发中,用户界面(UI)的设计至关重要。一个美观、直观的界面可以极大地提升用户体验。本文将介绍如何使用XAML来改善应用程序的UI设计,特别是如何通过使用DataTemplate和Style来美化列表项。
在之前的讨论中,有一个基础的应用程序,它看起来有点简陋,需要一些改进。首先,想添加一个样式,让艺术家列表看起来更加整洁。希望艺术家列表具有漂亮的外观和感觉,每个列表项看起来像一个带有圆角的按钮,并且包含专辑数量的计数。
要实现这种设计,首先需要添加一个DataTemplate,这样它就可以被列表项所使用。DataTemplate是一个模板,它被应用于没有默认显示方式的对象,并以它的类型名称显示。
注意,这也可以通过对Object.ToString()进行重写来实现,但这是客户端的帖子,所以不想改变模型代码来实现这个功能。
在App.xaml的Application.Resources部分添加了一个简单的DataTemplate,如下所示:
<DataTemplate DataType="{x:Type business:Artist}">
<TextBlock x:Name="contentHolder">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} - {1} albums">
<Binding Path="Name"/>
<Binding Path="Albums.Count"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Albums.Count}" Value="1">
<DataTrigger.Setters>
<Setter Property="TextBlock.Text" TargetName="contentHolder">
<Setter.Value>
<MultiBinding StringFormat="{}{0} - {1} album">
<Binding Path="Name"/>
<Binding Path="Albums.Count"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger.Setters>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
这里有几个要点:
可以使用转换器来完成整个字符串,但喜欢声明式的方式,因为可以一目了然地看到所有内容。对于那些喜欢使用转换器的人,可以将TextBlock的Text属性绑定到整个Artist({Binding}),然后使用如下的转换器:
public class ArtistStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string retVal = string.Empty;
var artist = value as Artist;
if (artist != null)
{
retVal += string.Format("{0} - {1} {2}", artist.Name, artist.Albums.Count, artist.Albums.Count == 1 ? "album" : "albums");
}
return retVal;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后在XAML中使用如下:
<local:ArtistStringConverter x:Key="artistConverter"/>
<DataTemplate DataType="{x:Type business:Artist}">
<TextBlock x:Name="contentHolder" Text="{Binding Converter={StaticResource artistConverter}}"/>
</DataTemplate>
一旦添加了这个(无论哪种方式),需要从ArtistList.xaml视图中移除DisplayMemberPath属性,以便使用模板。
现在,有了艺术家列表,显示了他们的名字和他们拥有的专辑总数,所以可以开始实际的风格,使列表项看起来像上面的图片。
希望所有三个列表看起来都一样,所以在app.xaml文件中添加了一个没有键的样式。如果想要为控件添加特定的样式,那么可以添加'x:Key="YourKeyName"'并使用'{StaticResource YourKeyName}'引用(在这种情况下,引用将在ListBox的ItemContainerStyle属性中)。
<Style TargetType="ListBoxItem">
<Style.Setters>
<Setter Property="Margin" Value="5,2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Rectangle Opacity="0.5" Height="30" StrokeThickness="1" x:Name="backBox" Stroke="Silver" RadiusX="5" RadiusY="5" Fill="Azure"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
在这个样式中,有一些事情正在进行:
最后,为专辑添加了一个新的DataTemplate——这看起来是一样的,只是类型和属性名称被更改为显示正确的东西,并且也重新排列了视图,如下所示:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Path=Artists}" Margin="5" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" SelectedItem="{Binding SelectedArtist}"/>
<ListBox ItemsSource="{Binding Path=SelectedArtist.Albums}" Margin="5" Grid.Column="1" Grid.Row="0" SelectedItem="{Binding SelectedAlbum}"/>
<ListBox ItemsSource="{Binding Path=SelectedAlbum.Tracks}" Margin="5" DisplayMemberPath="Name" Grid.Column="1" Grid.Row="1"/>
</Grid>