根据属性为WPF列表框项着色
我有一个可观察到的歌曲对象的集合。这些歌曲对象有一个名为“Playing”的属性,这是一个bool(我知道命名不好)。歌曲显示在我的应用程序的列表框中。我希望播放的歌曲是红色的。我整天都在使用触发器,试图让它工作起来。到目前为止,我已经达到了这样一种程度:当歌曲被添加到列表中时,它们的颜色是基于播放设置的。当播放属性改变时,是否可以使其改变? 这是我的XAML:根据属性为WPF列表框项着色,wpf,colors,triggers,listbox,listboxitem,Wpf,Colors,Triggers,Listbox,Listboxitem,我有一个可观察到的歌曲对象的集合。这些歌曲对象有一个名为“Playing”的属性,这是一个bool(我知道命名不好)。歌曲显示在我的应用程序的列表框中。我希望播放的歌曲是红色的。我整天都在使用触发器,试图让它工作起来。到目前为止,我已经达到了这样一种程度:当歌曲被添加到列表中时,它们的颜色是基于播放设置的。当播放属性改变时,是否可以使其改变? 这是我的XAML: <Window x:Class="MusicPlayer.MainWindow" xmlns="http://s
<Window x:Class="MusicPlayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MusicPlayer="clr-namespace:MusicPlayer" Title="Music" Height="350" Width="525" Name="Main">
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<Button Content="Play" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayButton_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Center" Margin="0,0,165,20" Name="stopButton" VerticalAlignment="Bottom" Width="75" Click="stopButton_Click" />
<Button Content="Next" Height="23" HorizontalAlignment="Center" Margin="165,0,0,20" Name="nextButton" VerticalAlignment="Bottom" Width="75" Click="nextButton_Click" />
<Button Content="Add Songs..." Height="23" HorizontalAlignment="Center" Margin="330,0,0,20" Name="AddButton" VerticalAlignment="Bottom" Width="75" Click="AddButton_Click" />
<Button Content="Previous" Height="23" HorizontalAlignment="Center" Margin="0,0,0,20" Name="PreviousButton" VerticalAlignment="Bottom" Width="75" Click="PreviousButton_Click" />
<Button Content="Pause" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Visibility="Hidden" Click="PauseButton_Click" />
<Menu Height="23" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Quit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<Slider Height="23" HorizontalAlignment="Stretch" Margin="10,0,10,50" Name="ProgressBar" VerticalAlignment="Bottom" />
</Grid>
</Window>
编辑:
implementign InotifyProperty更改后,颜色将使用高于或低于XAML的颜色更改为红色。现在,无论使用哪种方法,它都不会变回白色。我还有一个问题,我的播放方法不会将背景颜色更改为红色,但我的下一个方法会。这是我的密码:
这是我的新XAML:
<Window x:Class="MusicPlayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MusicPlayer="clr-namespace:MusicPlayer" Title="Music" Height="350" Width="525" Name="Main">
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}">
<TextBlock.Background>
<SolidColorBrush Color="{Binding BackgroundColor}"/>
</TextBlock.Background>
</TextBlock>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<Button Content="Play" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayButton_Click" />
<Button Content="Stop" Height="23" HorizontalAlignment="Center" Margin="0,0,165,20" Name="stopButton" VerticalAlignment="Bottom" Width="75" Click="stopButton_Click" />
<Button Content="Next" Height="23" HorizontalAlignment="Center" Margin="165,0,0,20" Name="nextButton" VerticalAlignment="Bottom" Width="75" Click="nextButton_Click" />
<Button Content="Add Songs..." Height="23" HorizontalAlignment="Center" Margin="330,0,0,20" Name="AddButton" VerticalAlignment="Bottom" Width="75" Click="AddButton_Click" />
<Button Content="Previous" Height="23" HorizontalAlignment="Center" Margin="0,0,0,20" Name="PreviousButton" VerticalAlignment="Bottom" Width="75" Click="PreviousButton_Click" />
<Button Content="Pause" Height="23" HorizontalAlignment="Center" Margin="0,0,330,20" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Visibility="Hidden" Click="PauseButton_Click" />
<Menu Height="23" HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Quit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<Slider Height="23" HorizontalAlignment="Stretch" Margin="10,0,10,50" Name="ProgressBar" VerticalAlignment="Bottom" />
</Grid>
</Window>
编辑2:
我刚刚注意到我有另一个问题。如果我突出显示其中一个具有白色背景的项目,则文本不可见。如何修复此问题?编辑3:
通过将背景设置为
颜色,修复了此问题。透明的而不是颜色。白色的具有播放属性的对象是否实现INotifyPropertyChanged?如果确实如此,那么您的UI应该根据您正在使用的DataTrigger方法自动更新
另一种方法是使用ViewModels而不是触发器(更容易理解和使用-当事情没有按预期进行时)
更新:
只是看看你的代码片段。我发现的一件事是,您需要在应用新值后触发事件
public Color BackgroundColor
{
get { return _backgroundColor; }
set
{
_backgroundColor = value;
NotifyPropertyChanged("BackgroundColor"); // must be after so that new value is readable by the GUI
}
}
此外,dataTemplate必须应用于listbox的ItemTemplate属性
<ListBox.ItemTemplate> <!-- not Resources property -->
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
我的列表框在每次单击时都会改变颜色!:) 为了让它变回原来的状态,难道你不需要在播放为False时实现一个触发器吗?像这样:
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Playing}" Value="False">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>
对我来说,这似乎是最简单的解决办法。当然,您可以将Value=“White”
更改为您需要的任何颜色。好的,我尝试了您建议的两种方法,但两种方法都有相同的问题。我真不敢相信我没有意识到必须实施INotifyPropertyChanged。现在,当我将Playing设置为true(在第一个方法中)或将BackgroundColor设置为Red(在第二个方法中)时,它会发生变化。问题是,我不能把它改回白色。你能帮忙吗?另外,由于某些原因,我的下一个方法可以改变颜色,但我的播放方法不能。哇!在那里添加NotifyPropertyChanged是我的愚蠢。我真不敢相信我做了那件事。在改变了这一点之后,现在一切都很好。我还将其更改为使用ItemTemplate。您能告诉我使用Resource和ItemTemplate的区别吗?我看不出有什么变化。Resource属性基本上是控件存储/检索资源的哈希表。它通常用于存储命名对象(例如画笔、样式、数据模板),然后在控件的绑定或属性中按名称引用这些对象。ItemTemplate属性指定ItemsControl应用于显示每个项目的模板。MSDN在解释所有这些方面做得更好——如果我没记错的话,在值返回超出范围时触发回滚。谢谢。这个解决方案也是我第一次想到的。根据其他答案,我认为这个解决方案行不通。所以,谢谢你花时间回答,但你没有预料到我会犯多么愚蠢的错误导致这个问题。
<ListBox HorizontalAlignment="Stretch" Name="Playlist" VerticalAlignment="Stretch" Margin="0,23,0,79" MouseDoubleClick="Playlist_MouseDoubleClick">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Playing}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Playing}" Value="False">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type MusicPlayer:Song}">
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</ListBox.Resources>