Цвет элемента списка WPF WPF на основе свойства - PullRequest
1 голос
/ 31 мая 2011

У меня есть наблюдаемая коллекция объектов Песни. У этих объектов песни есть свойство «Playing», которое является «bool» (я знаю, плохое наименование). Песни отображаются в ListBox в моем приложении. Я хочу, чтобы песня, которая играет, была окрашена в красный цвет. Я работал с триггерами весь день, пытаясь сделать эту работу. До сих пор я дошел до того, что они окрашены в зависимости от того, на что настроено воспроизведение при добавлении песни в список. Можно ли изменить его при изменении свойства Playing? Вот мой 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:

<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.

Ответы [ 2 ]

4 голосов
/ 31 мая 2011

Чтобы вернуть его обратно, вам также не нужно было бы реализовать триггер, когда Playing равно 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" на любой нужный вам цвет.

2 голосов
/ 31 мая 2011

Ваш объект со свойством Playing реализует INotifyPropertyChanged? Если это так, то ваш пользовательский интерфейс должен автоматически обновляться в соответствии с подходом 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 должен быть применен к свойству ItemTemplate списка

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

Я в основном изменил фрагмент из примера, который я разместил, чтобы использовать ваш класс песни, а затем изменил нажатие кнопки, чтобы переключаться между 2 цветами. (Также превратил ListView в 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;
        }

Мои списки меняют цвет при каждом нажатии! :)

...