提升XAML界面风格与细节

在现代应用程序开发中,用户界面的美观度越来越受到重视。一个简洁、美观的界面不仅能提升用户体验,还能更好地传达信息。本文将介绍如何通过XAML来提升应用程序界面的风格和细节。

基础应用的美化

在之前的讨论中,有一个基础的应用界面,虽然功能齐全,但外观上略显简陋。为了提升界面的美观度,首先需要对艺术家列表进行美化。希望艺术家列表具有圆润的按钮样式,并显示艺术家的专辑数量。每个列表项的外观应该类似于以下样式:

为了实现这种设计,首先需要添加一个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>

这里发生了几件事情:

  • 第一行声明了这个模板关联的类型 - 必须首先在文件中添加命名空间,以便它能够正常工作。
  • MultiBinding有一个关联的StringFormat - 这与普通的字符串格式化相同,只是“{}”在等号后面 - 这仅仅是为了转义格式化字符串。
  • 绑定到Albums.Count - 是的,可以绑定到“内置”属性。
  • DataTrigger是一个简单的方式,表示如果只有一个专辑,那么后面的文本不应该有“s”结尾。

可以使用一个转换器来完成整个字符串,但喜欢声明式的方式,因为可以在同一地方看到所有正在进行的操作。对于那些喜欢使用转换器的人,会将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>

在这个样式中,做了几件事情:

  • 它针对ListBoxItem,因为这是要样式化的控件(不是ListBox本身)。
  • 边距将项目很好地分隔开。
  • 实际的样式部分包含在一个ControlTemplate中,然后分配给ListBoxItem的Template属性。
  • ContentPresenter将呈现它被赋予的任何内容,在这种情况下,它呈现了传入的DataTemplate
  • 这里的触发器表示当ListBoxItem被选中时,希望改变矩形的填充颜色,以指示选择了一个项目。

最后,为专辑添加了一个新的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>
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485