Изменение свойства xaml в соответствии со старым значением и новым значением - PullRequest
0 голосов
/ 27 марта 2020

У меня есть приложение Xamarin Forms. Я использую MVVM. ContentPage имеет ListView, как показано ниже. ItemSource обновляется автоматически каждые 10 секунд из службы удаленного отдыха. Я хотел бы изменить свойство Label TextColor, когда старое значение отличается от нового значения. Каков наилучший подход XAML для этого? Заранее спасибо

<ListView HasUnevenRows="True" ItemsSource="{Binding Items}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid>
                        <Label
                            Grid.Column="0"
                            Text="{Binding ValueA}"
                            TextColor="Black" />
                        <Label
                            Grid.Column="1"
                            Text="{Binding ValueB}"
                            TextColor="Black" />
                        <Label
                            Grid.Column="2"
                            Text="{Binding ValueC}"
                            TextColor="Black" />
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

РЕДАКТИРОВАТЬ: Ой, я неправильно прочитал, думал, что вы хотели изменить цвет текста для новых элементов. Обновил ниже, чтобы он изменил цвет фона элемента, если элемент был добавлен, и изменит цвет текста для значения, если оно изменилось с момента последнего refre sh.

. Вы хотите связать свойство TextColor для Label в логическое значение, указывающее, изменилось ли значение или нет, и вам потребуется использовать ValueConverter для преобразования логического значения в цвет.

Вот простой пример (большая часть приведенного ниже кода предназначена для имитации добавления и обновления элементов в списке, интересными объектами являются преобразователи значений и способы их использования для превращения связанного значения bool в цвет):

MainPage.xaml.cs: (включает конвертеры и модель представления элемента)

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Timers;
using Xamarin.Forms;

namespace ChangeTextColorForNewItemsInListView
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public ObservableCollection<ItemViewModel> Items { get; set; } = new ObservableCollection<ItemViewModel>();
        Timer _timer; 
        int itemNumber = 0;
        Random randomNumber = new Random(DateTime.Now.Millisecond);


        public MainPage()
        {
            InitializeComponent();
            BindingContext = this;
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            for (int i = 0; i < 10; i++)
            {
                Items.Add(new ItemViewModel
                {
                    ValueA = $"ValueA {++itemNumber}",
                    ValueB = $"ValueB {itemNumber}",
                    ValueC = $"ValueC {itemNumber}",
                    IsNew = true
                });
            }

            _timer = new Timer(2000);
            _timer.AutoReset = true;
            _timer.Elapsed += Timer_Elapsed;
            _timer.Start();
        }

        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            foreach (var item in Items)
            {
                item.IsNew = false;
                item.ValueA = item.ValueA.Replace(" new", "");
                item.ValueB = item.ValueB.Replace(" new", "");
                item.ValueC = item.ValueC.Replace(" new", "");
                item.ValueAChanged = false;
                item.ValueBChanged = false;
                item.ValueCChanged = false;

                int changeValue = randomNumber.Next(0, 15);
                switch (changeValue)
                {
                    case 0:
                        item.ValueA = item.ValueA.Replace(" new","") + " new";
                        break;
                    case 1:
                        item.ValueB = item.ValueB.Replace(" new", "") + " new";
                        break;
                    case 2:
                        item.ValueC = item.ValueC.Replace(" new", "") + " new";
                        break;
                    default:
                        break;

                }
            }

            for (int i = 0; i < randomNumber.Next(1,5); i++)
            {
                Items.Insert(randomNumber.Next(1, Items.Count -1)  ,new ItemViewModel
                {
                    ValueA = $"ValueA {++itemNumber}",
                    ValueB = $"ValueB {itemNumber}",
                    ValueC = $"ValueC {itemNumber}",
                    IsNew = true
                });
            }       
        }
    }

    public class ItemViewModel : INotifyPropertyChanged
    {
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        bool _isNew;
        public bool IsNew
        {
            get => _isNew;
            set
            {
                if (_isNew != value)
                {
                    _isNew = value;
                    OnPropertyChanged();
                }
            }
        }

        bool _valueAChanged;
        public bool ValueAChanged
        {
            get => _valueAChanged;
            set
            {
                if (_valueAChanged != value)
                {
                    _valueAChanged = value;
                    OnPropertyChanged();
                }
            }
        }
        string _valueA;
        public string ValueA
        {
            get => _valueA;
            set
            {
                if (_valueA != value)
                {
                    _valueA = value;
                    ValueAChanged = true;
                    OnPropertyChanged();
                }
            }
        }

        bool _valueBChanged;
        public bool ValueBChanged
        {
            get => _valueBChanged;
            set
            {
                if (_valueBChanged != value)
                {
                    _valueBChanged = value;
                    OnPropertyChanged();
                }
            }
        }
        string _valueB;
        public string ValueB
        {
            get => _valueB;
            set
            {
                if (_valueB != value)
                {
                    _valueB = value;
                    ValueBChanged = true;
                    OnPropertyChanged();
                }
            }
        }

        bool _valueCChanged;
        public bool ValueCChanged
        {
            get => _valueCChanged;
            set
            {
                if (_valueCChanged != value)
                {
                    _valueCChanged = value;
                    OnPropertyChanged();
                }
            }
        }
        string _valueC;
        public string ValueC
        {
            get => _valueC;
            set
            {
                if (_valueC != value)
                {
                    _valueC = value;
                    ValueCChanged = true;
                    OnPropertyChanged();
                }
            }
        }
    }

    public class BoolToColorConverterNewItem : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? Color.Yellow : Color.White;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException("No need to convert from color to bool");
        }
    }

    public class BoolToColorConverterChangedValue : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? Color.Red : Color.Black;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException("No need to convert from color to bool");
        }
    }
}

MainPage.xaml:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:d="http://xamarin.com/schemas/2014/forms/design"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                xmlns:local="using:ChangeTextColorForNewItemsInListView"
                mc:Ignorable="d"
                x:Class="ChangeTextColorForNewItemsInListView.MainPage"

                >
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:BoolToColorConverterChangedValue x:Key="boolToColorCV" />
            <local:BoolToColorConverterNewItem x:Key="boolToColorNI" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Margin="0,50,0,0">
        <!-- Place new controls here -->
        <ListView HasUnevenRows="True" ItemsSource="{Binding Items}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid BackgroundColor="{Binding IsNew, Converter={StaticResource boolToColorNI}}">
                            <Label
                                Grid.Column="0"
                                Text="{Binding ValueA}"
                                TextColor="{Binding ValueAChanged, Converter={StaticResource boolToColorCV}}" />
                            <Label
                                Grid.Column="1"
                                Text="{Binding ValueB}"
                                TextColor="{Binding ValueBChanged, Converter={StaticResource boolToColorCV}}" />
                            <Label
                                Grid.Column="2"
                                Text="{Binding ValueC}"
                                TextColor="{Binding ValueCChanged, Converter={StaticResource boolToColorCV}}" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

enter image description here

1 голос
/ 27 марта 2020

Вы можете привязать значение TextColor

в xaml

<Label
     Grid.Column="1"
     Text="{Binding ValueB}"
     TextColor="{Binding TitleColor}" />

в модели

public class MyModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    Color color;
    public Color TitleColor
    {
        get { return color; }

        set
        {

            if (color != value&& color != null)
            {
                color = value;
                NotifyPropertyChanged("TitleColor");
            }

        }
    }       

    private string valueB;
    public string ValueB
    {
        get { return valueB; }

        set
        {
            if (valueB != value)
            {
                valueB = value;

                TitleColor= Color.Red;  // change color here 

                NotifyPropertyChanged("ValueB");
            }
        }
    }

    //...other property

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...