根据属性为WPF列表框项着色

根据属性为WPF列表框项着色,wpf,colors,triggers,listbox,listboxitem,Wpf,Colors,Triggers,Listbox,Listboxitem,我有一个可观察到的歌曲对象的集合。这些歌曲对象有一个名为“Playing”的属性,这是一个bool(我知道命名不好)。歌曲显示在我的应用程序的列表框中。我希望播放的歌曲是红色的。我整天都在使用触发器,试图让它工作起来。到目前为止,我已经达到了这样一种程度:当歌曲被添加到列表中时,它们的颜色是基于播放设置的。当播放属性改变时,是否可以使其改变? 这是我的XAML: <Window x:Class="MusicPlayer.MainWindow" xmlns="http://s

我有一个可观察到的歌曲对象的集合。这些歌曲对象有一个名为“Playing”的属性,这是一个bool(我知道命名不好)。歌曲显示在我的应用程序的列表框中。我希望播放的歌曲是红色的。我整天都在使用触发器,试图让它工作起来。到目前为止,我已经达到了这样一种程度:当歌曲被添加到列表中时,它们的颜色是基于播放设置的。当播放属性改变时,是否可以使其改变? 这是我的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>
                <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>