根据属性为 WPF ListBox 项着色 [英] Color a WPF ListBox item based on a property

查看:16
本文介绍了根据属性为 WPF ListBox 项着色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可观察的 Song 对象集合.这些歌曲对象有一个名为播放"的属性,它是一个布尔值(我知道命名错误).歌曲显示在我的应用程序的列表框中.我希望正在播放的歌曲为红色.我一整天都在使用触发器试图使这项工作发挥作用.到目前为止,我已经到了根据歌曲添加到列表时播放设置的颜色对它们进行着色的程度.是否可以在 Playing 属性更改时更改它?这是我的 XAML:

I have an observable collection of Song objects. These song objects have a property called "Playing" that is a bool (bad naming, I know). The songs display in a ListBox in my application. I want the song that is Playing to be colored red. I have been working with triggers all day trying to make this work. So far, I have gotten to the point where they are colored based on what Playing is set to when the song is added to the list. Is it possible to make it change when the Playing property changes? Here is my 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>

在实现 INotifyPropertyChanged 后,颜色将使用上面或下面的 XAML 更改为红色.现在,使用任何一种方法都不会变回白色.我也有一个问题,我的 Play 方法不会将背景颜色更改为红色,但我的下一个方法会.这是我的代码:http://pastebin.com/EMTUpTin http://pastebin.com/LuK78zGp这是我的新 XAML:

After implementign INotifyPropertyChanged, The color will change to red using either the above or below XAML. Now, it won't change back white using either method. I am also having a problem where my Play method will not change the background color to red, but my next method will. Here is my code: http://pastebin.com/EMTUpTin http://pastebin.com/LuK78zGp Here is my new 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:通过将背景设置为 Colors.Transparent 而不是 Colors.White 来解决此问题.

Edit 2: I just noticed I am having another problem. If I highlight one of the items with a white background, the text is invisible. How do I fix this?
Edit 3: Fixed this problem by setting the background to Colors.Transparent instead of Colors.White.

推荐答案

您的具有 Playing 属性的对象是否实现了 INotifyPropertyChanged ?如果是,那么您的 UI 应根据您使用的 DataTrigger 方法自动更新.

Does your object with the Playing property implement INotifyPropertyChanged ? If it does, then your UI should auto-update based on the DataTrigger approach you are using.

另一种方法是使用 ViewModels 而不是触发器(更容易理解和使用 - 当事情没有按预期进行时)一个例子

Another approach is to use ViewModels instead of Triggers (easier to understand and work with - when things don't go as expected) An example

更新:刚刚看了你的代码片段.我发现一件事 - 您需要在应用新值后触发事件.

Update: Just looked at your code snippets. One thing I found - you need to trigger the event after you've applied the new value.

public Color BackgroundColor
        {
            get { return _backgroundColor; }

            set
            {
                _backgroundColor = value;
                NotifyPropertyChanged("BackgroundColor"); // must be after so that new value is readable by the GUI
            }
        }

此外,dataTemplate 必须应用于列表框的 ItemTemplate 属性

Also the dataTemplate must be applied to the ItemTemplate property of the listbox

<ListBox.ItemTemplate> <!-- not Resources property -->
                <DataTemplate DataType="{x:Type MusicPlayer:Song}">

我基本上将我发布的示例中的片段更改为使用您的歌曲类,然后修改按钮单击以在 2 种颜色之间切换.(也把ListView变成了ListBox)

I basically changed the snippet from the example that I posted to use your song class and then modified the button click to toggle between 2 colors. (Also turned ListView into ListBox)

private bool _isGreen = false;
        private void Button_Click(object sender, RoutedEventArgs e)
        {

            foreach (var item in Items)
                item.BackgroundColor = (_isGreen ? Colors.Cyan : Colors.PaleGreen );
            _isGreen = !_isGreen;
        }

我的列表框在每次点击时都会改变颜色!:)

My listboxes change color on every click! :)

这篇关于根据属性为 WPF ListBox 项着色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆