简体   繁体   English

每当值更改时,更改 uwp 中列表视图项的背景颜色

[英]Change background color of list view item in uwp whenever the value changes

I have a listview with values that are being updated constantly from a different thread.我有一个列表视图,其中的值从不同的线程不断更新。 I want to change the color of the background according to the value of the item.我想根据项目的值来改变背景的颜色。 After reading a lot I came to the following conclusions:在阅读了很多之后,我得出以下结论:

  • The correct way to set background color for list view item is via style selector.为列表视图项设置背景颜色的正确方法是通过样式选择器。
  • Style selector is called only once in the initialization of the list.样式选择器在列表的初始化中只被调用一次。

How can I achieve this simple behavior?我怎样才能实现这种简单的行为?

xaml: xaml:

<Page
    x:Class="MyProject.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyProject"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView ItemsSource="{x:Bind ViewModel.DataRef.Values, Mode=OneWay}" HorizontalAlignment="Center" VerticalAlignment="Center">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:ValWrapper">
                    <TextBlock Text="{x:Bind Val, Mode=OneWay}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyleSelector>
                <local:CustomItemContainerStyleSelector>
                    <local:CustomItemContainerStyleSelector.Bad>
                        <Style TargetType="ListViewItem">
                            <Setter Property="Background" Value="Red"/>
                            
                        </Style>
                    </local:CustomItemContainerStyleSelector.Bad>

                    <local:CustomItemContainerStyleSelector.Good>
                        <Style TargetType="ListViewItem">
                            <Setter Property="Background" Value="Green"/>
                        </Style>
                    </local:CustomItemContainerStyleSelector.CloseToBad>
                </local:CustomItemContainerStyleSelector>
            </ListView.ItemContainerStyleSelector>
        </ListView>
    </Grid>
</Page>

cs: CS:

public sealed partial class MainPage : Page
{
    public ViewModel ViewModel { get; set; }

    public MainPage()
    {
        this.InitializeComponent();
        this.ViewModel = new ViewModel();

    }

}

public class CustomItemContainerStyleSelector : StyleSelector
{
    public Style Bad { get; set; }
    public Style Good { get; set; }


    protected override Style SelectStyleCore(object item, DependencyObject container)
    {
        double threshold = 1;
        ValWrapper v = (ValWrapper)item;
        if (v.Val <= threshold)
        {
            return Bad;
        }
        else {
            return Good;
        }
    }
}

Whenever the data changes, "NotifyPropertyChanged" is called (implements INotifyPropertyChanged).每当数据更改时,都会调用“NotifyPropertyChanged”(实现 INotifyPropertyChanged)。

Please check the following steps:请检查以下步骤:

  1. Set a temporary variable _tempValue to record previous number.设置一个临时变量_tempValue来记录以前的数字。
  2. Bind the Background property to IsUpdate , the initial value is all false .Background属性绑定到IsUpdate ,初始值全部为false
  3. If the number changes, please set IsUpdate to true , then the Background of ListViewItem turns red .如果数字发生变化,请将IsUpdate设置为true ,然后ListViewItemBackground变为red

XAML: XAML:

<Page
    x:Class="Permisson.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Permisson"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.Resources>
        <local:ColorConverter x:Key="ColorConverter"/>
    </Page.Resources>
    <Grid>
        <StackPanel>
            <ListView ItemsSource="{x:Bind ViewModel.DataRef, Mode=OneWay}" HorizontalAlignment="Center" VerticalAlignment="Center">
                <ListView.ItemTemplate >
                    <DataTemplate x:DataType="local:ValWrapper">
                        <Grid Background="{Binding IsUpdate, Converter={StaticResource ColorConverter},Mode=OneWay}">
                            <TextBlock Text="{Binding Val, Mode=OneWay}"/>
                        </Grid>
                    </DataTemplate>

                </ListView.ItemTemplate>
             
            </ListView>
            <Button Content="ChangeNum" Click="Button_Click"/>
            <Button Content="ChangeNum2" Click="Button_Click_1"/>        
        </StackPanel>
   
    </Grid>
</Page>

Code behind:后面的代码:

namespace Permisson
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public ViewModel ViewModel { get; set; }

        public MainPage()
        {
            this.InitializeComponent();

            this.ViewModel = new ViewModel();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var v = ViewModel.DataRef[0];
       
            v.Val = 9;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            var v = ViewModel.DataRef[1];         
            v.Val = 10;
        }
    }
    public class ViewModel
    {
        private ObservableCollection<ValWrapper> dataRef = new ObservableCollection<ValWrapper>()
        {
            new ValWrapper {Val=22,Brush=new SolidColorBrush (Colors.Green),IsUpdate = false },
            new ValWrapper {Val=25,Brush=new SolidColorBrush (Colors.Green),IsUpdate = false},
            new ValWrapper {Val=35,Brush=new SolidColorBrush (Colors.Green),IsUpdate = false},
            new ValWrapper {Val=45,Brush=new SolidColorBrush (Colors.Green),IsUpdate = false },
            new ValWrapper {Val=55,Brush=new SolidColorBrush (Colors.Green),IsUpdate = false},
            new ValWrapper {Val=65,Brush=new SolidColorBrush (Colors.Green),IsUpdate = false }

        };
        public ObservableCollection<ValWrapper> DataRef { get { return dataRef; } }

    }
    public class ColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var color = new SolidColorBrush();
            if ((bool)value)
            {
                color.Color = Colors.Red;
            }
            else
            {
                color.Color = Colors.Green;

            }
            return color;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }


    public class ValWrapper : INotifyPropertyChanged
    {
        private int val;
        private SolidColorBrush brush;
        public SolidColorBrush Brush
        {
            get { return brush; }
            set
            {
                brush = value;
                RaisePropertyChanged();
            }
        }


        private int _tempValue;
        public int Val
        {
            get { return val; }
            set
            {
               if(_tempValue != value && _tempValue != 0)
                {
                    IsUpdate = true;
                }
                val = value;
                RaisePropertyChanged();
                _tempValue = val;
            }
        }
        private bool _isUpdate;
        public bool IsUpdate
        {
            set
            {
                _isUpdate = value;
                RaisePropertyChanged();
            }
            get
            {
                return _isUpdate;

            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged([CallerMemberName] string propertyname = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyname));

            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM