Masti Broz Top
Masti Broz Top

Reputation: 89

how to access child elements in a collection view?

i am making frames in collection view and i want to change the background color of frames whenever i select the frames but the problem is that i cannot access my frames from the collection view and when i click on the frame it picks the default orange color.

i made small changes in my frame model class where i want to change text color of my label as like we did the color of frame here is the code but it is not working this code is in frame model class

public Color LabelColor
    {
        set
        {
            if (txtcolor != value)
            {
                txtcolor = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("labelcolor"));
                }
            }
        }
        get
        {
            return firstFrameBackColor;
        }
    }

here i access this in my CS Class

 FrameModel previous = (e.PreviousSelection.FirstOrDefault() as FrameModel);
        FrameModel current = (e.CurrentSelection.FirstOrDefault() as FrameModel);

        //Set the current to the color you want
        try
        {
            current.FirstFrameBackColor = Color.FromRgb(74, 152, 247);
            current.LabelColor = Color.White;
            // current.SecondFrameBackColor = Color.Green;
        }
        catch (Exception ex)
        {
            ex.Message.ToString();
            throw;
        }

       // current.SecondFrameBackColor = Color.Green;

        if (previous != null)
        {
            //Reset the previous to defaulr color
            previous.FirstFrameBackColor = Color.White;
            current.LabelColor = Color.Black;
            //previous.SecondFrameBackColor = Color.Purple;
        }

Upvotes: 1

Views: 4189

Answers (2)

nevermore
nevermore

Reputation: 15786

when i give x:name property to my child views inside the collection view i cant access them in my C# class

You can't access items in templates from the code behind by name because there may be 0 or 1000 copies of that template created at run time.

Refer this discussion: cannot-reach-control-x-name-inside-listview

In your case, instead of access the control in the template, you can set the background property binding to the property in the model, for example:

            <Frame
                        WidthRequest="20"
                        HeightRequest="20"   
                        Margin="0,-30,0,10"
                        HorizontalOptions="End"
                        CornerRadius="10"
                        Padding="5"
                        BackgroundColor="{Binding SecondFrameBackColor}">
                <Label
                            Text="5"
                            TextColor="#FFFFFF"
                            HorizontalTextAlignment="Center"
                            VerticalTextAlignment="Center"                                       
                    >

                </Label>
            </Frame>

Here is the model:

class myModel : INotifyPropertyChanged
{

    Color firstFrameBackColor;

    Color secondFrameBackColor;

    public event PropertyChangedEventHandler PropertyChanged;

    public myModel()
    {

    }

    public Color FirstFrameBackColor
    {
        set
        {
            if (firstFrameBackColor != value)
            {
                firstFrameBackColor = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("FirstFrameBackColor"));
                }
            }
        }
        get
        {
            return firstFrameBackColor;
        }
    }

    public Color SecondFrameBackColor
    {
        set
        {
            if (secondFrameBackColor != value)
            {
                secondFrameBackColor = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("SecondFrameBackColor"));
                }
            }
        }
        get
        {
            return secondFrameBackColor;
        }
    }
}

The itemSoure:

public partial class MainPage : ContentPage
{
    ObservableCollection<myModel> models = new ObservableCollection<myModel>();

    public MainPage()
    {
        InitializeComponent();

        myModel model1 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };
        myModel model2 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };
        myModel model3 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };
        myModel model4 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };
        myModel model5 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };
        myModel model6 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };
        myModel model7 = new myModel() { FirstFrameBackColor = Color.White, SecondFrameBackColor = Color.Purple };

        models.Add(model1);
        models.Add(model2);
        models.Add(model3);
        models.Add(model4);
        models.Add(model5);
        models.Add(model6);
        models.Add(model7);

        CNlist.ItemsSource = models;
    }

And in the SelectionChanged event, change the background to what you want:

private void CNlist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

    myModel previous = (e.PreviousSelection.FirstOrDefault() as myModel) ;
    myModel current = (e.CurrentSelection.FirstOrDefault() as myModel);

    //Set the current to the color you want
    current.FirstFrameBackColor = Color.Pink;
    current.SecondFrameBackColor = Color.Green;

    if (previous != null)
    {
        //Reset the previous to defaulr color
        previous.FirstFrameBackColor = Color.White;
        previous.SecondFrameBackColor = Color.Purple;
    }

}

Here is the result:

screen

I updated my sample here and you can check it. Let me know if it works to you!

Upvotes: 1

Bruno Caceiro
Bruno Caceiro

Reputation: 7179

From the CollectionView Spec:

The orange color is actually the value for state_activated in your Android app's theme. So not everyone will see orange; that's just the AppCompat default. This is the fallback value if nothing else has been specified.

When an item in the CollectionView is selected, the VisualState for the root Forms element of the item is changed to Selected. You can use the VisualStateManager to manage what a selected item looks like. For an example of this, take a look at the SelectionModeGallery in Control Gallery. On that page, the background color for the selected item is being set to LightSkyBlue. Any other Forms property can also be set; for instance, try adding to the tag.

At the moment, this is somewhat limited; you can really only modify the root element in your ItemTemplate.

So, to answer your question, it will not work, since your Frame is not the Root element from your ItemTemplate. Either you apply that in your StackLAyout, or in the SelectedItem, you change manually the background color of your element.

Upvotes: 0

Related Questions