在这里,我想以某种方式设置列表框项目的样式,即向某些项目添加一点斜体注释,如下图所示。
让我接近的是使用
Inline
项目列表作为 ItemsSource 并添加一些 System.Windows.Documents.Run
对象。我采用这种方法面临两个挑战:
List<Inline>
作为 ItemsSource 会覆盖列表框的悬停和项目选择机制。不再可能通过单击来选择项目,并且悬停在效果上只是闪烁。如何解决这两个问题?或者有人知道更好的方法吗?
这是一个小工作示例:
<Window x:Class="SandboxListbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ListBoxWithColoredItems"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<ListBox
ItemsSource="{Binding Path=Items}"
SelectedItem="{Binding Path=SelectedItem}"/>
</Grid>
</Window>
namespace SandboxListBox
{
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
Run italic = new Run("Italic text") { FontStyle = FontStyles.Italic };
Run reg2 = new Run("Another Regular Tet");
Run reg = new Run("Regular Tet");
Run fontfamily = new Run("Another font") { FontFamily = new FontFamily("Comic Sans MS, Verdana") };
Run big = new Run(" - big") { FontSize = 20 };
Items = new List<Inline> { reg, fontfamily, reg2, italic };
}
private List<Inline> items;
public List<Inline> Items
{
get => items;
set
{
items = value;
OnPropertyChanged();
}
}
private Inline selecteditem;
public Inline SelectedItem
{
get => selecteditem;
set
{
selecteditem = value;
OnPropertyChanged();
}
}
// INotifyPropertyChanged implementation left out
}}
您可以在列表框的 ItemTemplate 中进行文本格式化,例如
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Text, Mode=OneWay}"/>
<Run Text="{Binding Comment, Mode=OneWay}" FontStyle="Italic"/>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
将上面的内容与这样的视图模型一起使用:
public class Item
{
public string Text { get; set; }
public string Comment { get; set; }
}
public class ViewModel
{
public ObservableCollection<Item> Items { get; }
= new ObservableCollection<Item>();
}