使用XAML改善UI设计

在现代应用程序开发中,用户界面(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>

这里有几个要点:

  • 第一行声明了这个模板所关联的类型。
  • 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