locked
listView: change color of one item if statement is true RRS feed

  • Question

  • User393906 posted

    Hi,

    I have a listView with the following content:

    xaml:

    xaml.cs:

    As you can see: the list consists of 5 items, all which have the color black (see .xaml).

    I will add an if-statement soon. When this statement returns 'true', the color of Text4 only should turn to the color Red, overwriting the color black. So the result would then be a list with Text1, Text2, Text3 and Text5 in the color Black, and Text4 in the color Red.

    How can I achieve this?

    Regards, Ganesh

    Sunday, May 3, 2020 12:43 AM

Answers

  • User369978 posted

    You could refer the following steps .

    1. Convert the binding content from string list to model list , the model has two properties (text and color) used to binding on label .

    2. Make model class implement INotifyPropertyChanged .

    3. Modify the property if the statement becomes true .

    Sample

    Model

      public class Model : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            // This method is called by the Set accessor of each property.  
            // The CallerMemberName attribute that is applied to the optional propertyName  
            // parameter causes the property name of the caller to be substituted as an argument.  
            private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private string text;
            public string Text
            {
                get
                {
                    return this.text;
                }
    
                set
                {
                    if (value != this.text)
                    {
                        this.text = value;
                        NotifyPropertyChanged();
                    }
                }
            }
    
            private Color color;
            public Color Color
            {
                get
                {
                    return this.color;
                }
    
                set
                {
                    if (value != this.color)
                    {
                        this.color = value;
                        NotifyPropertyChanged();
                    }
                }
            }
        }
    

    Page Xaml

     <ContentPage.ToolbarItems>
            <ToolbarItem Text="Change" Clicked="ToolbarItem_Clicked"/>
        </ContentPage.ToolbarItems>
        <ContentPage.Content>
            <ListView x:Name="listView">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell >
                            <Label Text="{Binding Text}" TextColor="{Binding Color}"/>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </ContentPage.Content>
    

    Page code behind

    [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class Page1 : ContentPage
        {
    
            public List<Model> list { get; set; }
    
            public Page1()
            {
                InitializeComponent();
    
                list = new List<Model>();
    
    
                for(int i = 0; i< 5; i++)
                {
                    Model model = new Model();
                    model.Text = "Text" + (i+1).ToString();
                    model.Color = Color.Black;
                    list.Add(model);
                }
    
                listView.ItemsSource = list;
            }
    
    
    
    
            bool statement = false;
            private void ToolbarItem_Clicked(object sender, EventArgs e)   
            {
                 //here i use button click to trigger the change of statement .
                statement = true;
    
                if (statement)
                {
                    var model = list[3];
                    model.Color = Color.Red;
                }
            }
        }
    

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Monday, May 4, 2020 2:49 AM
  • User369978 posted

    The binding works but the path is incorrect , you have to specify the model property name(not dot) on the label in viewcell.

                     <ViewCell >
                        <Label Text="{Binding Text}" TextColor="{Binding Color}"/>    //Text and Color is the property name defined in model class 
                    </ViewCell>
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, May 5, 2020 6:27 AM

All replies

  • User74 posted

    ItemsSource should be populated with a list of models instead of strings, the model contains a property that you can bind to to set the colour to black or red as per your logic.

    Sunday, May 3, 2020 6:31 AM
  • User393906 posted

    Thanks for the response.

    I'm very new to data binding and I don't know (yet) how to implement it. I saw this Documentation https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/data-and-databinding , but I'm still having difficulties with it.

    Are you able to help me a bit?

    Regards, Ganesh

    Sunday, May 3, 2020 12:13 PM
  • User393322 posted

    In XAML define a resource like:: Then

                default:
                    return Color.Black;
            }
    
        }
    
    Sunday, May 3, 2020 5:34 PM
  • User393322 posted

    The resource definition went missing... local:StatusToColorConverter x:Key="StatusToColorConverter"

    Sunday, May 3, 2020 5:35 PM
  • User369978 posted

    You could refer the following steps .

    1. Convert the binding content from string list to model list , the model has two properties (text and color) used to binding on label .

    2. Make model class implement INotifyPropertyChanged .

    3. Modify the property if the statement becomes true .

    Sample

    Model

      public class Model : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            // This method is called by the Set accessor of each property.  
            // The CallerMemberName attribute that is applied to the optional propertyName  
            // parameter causes the property name of the caller to be substituted as an argument.  
            private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private string text;
            public string Text
            {
                get
                {
                    return this.text;
                }
    
                set
                {
                    if (value != this.text)
                    {
                        this.text = value;
                        NotifyPropertyChanged();
                    }
                }
            }
    
            private Color color;
            public Color Color
            {
                get
                {
                    return this.color;
                }
    
                set
                {
                    if (value != this.color)
                    {
                        this.color = value;
                        NotifyPropertyChanged();
                    }
                }
            }
        }
    

    Page Xaml

     <ContentPage.ToolbarItems>
            <ToolbarItem Text="Change" Clicked="ToolbarItem_Clicked"/>
        </ContentPage.ToolbarItems>
        <ContentPage.Content>
            <ListView x:Name="listView">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell >
                            <Label Text="{Binding Text}" TextColor="{Binding Color}"/>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </ContentPage.Content>
    

    Page code behind

    [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class Page1 : ContentPage
        {
    
            public List<Model> list { get; set; }
    
            public Page1()
            {
                InitializeComponent();
    
                list = new List<Model>();
    
    
                for(int i = 0; i< 5; i++)
                {
                    Model model = new Model();
                    model.Text = "Text" + (i+1).ToString();
                    model.Color = Color.Black;
                    list.Add(model);
                }
    
                listView.ItemsSource = list;
            }
    
    
    
    
            bool statement = false;
            private void ToolbarItem_Clicked(object sender, EventArgs e)   
            {
                 //here i use button click to trigger the change of statement .
                statement = true;
    
                if (statement)
                {
                    var model = list[3];
                    model.Color = Color.Red;
                }
            }
        }
    

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Monday, May 4, 2020 2:49 AM
  • User393906 posted

    Hi ColeX,

    Thanks for the answer, it seems to work except my listView displays something strange. My Page is located in the folder Pages and my Model is located in the folder Utils.Models:

    This is the result in my list with your exact code:

    Do you know what's the problem here?

    Regards, Ganesh

    Monday, May 4, 2020 2:30 PM
  • User369978 posted

    The binding works but the path is incorrect , you have to specify the model property name(not dot) on the label in viewcell.

                     <ViewCell >
                        <Label Text="{Binding Text}" TextColor="{Binding Color}"/>    //Text and Color is the property name defined in model class 
                    </ViewCell>
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, May 5, 2020 6:27 AM
  • User393906 posted

    Thanks a lot!

    Tuesday, May 5, 2020 2:07 PM