XAML - Change Label Text from code behind

AsknetAsknet USMember ✭✭
edited December 2016 in Xamarin.Forms

Hi everybody,
I need to change a label text put into a Viewcell from codebehind but I receive an error dispayng "the name myLabel does not exist in the current context".

this is my 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" x:Class="CarouselPageNavigation.EditOrderPage">
    <ContentPage.Content>
        <StackLayout VerticalOptions="FillAndExpand" Orientation="Vertical">

            <Label x:Name="oName" Text="" />
            <Label x:Name="countProducts" Text="" />
            <ListView x:Name="ProductList" >
              <ListView.ItemTemplate>
                <DataTemplate>
                  <ViewCell BindingContextChanged="OnBindingContextChanged">

                        <Grid>
                            <StackLayout Orientation="Horizontal" Padding="10,5,0,5" >
                                <StackLayout Orientation="Horizontal">
                                    <Image Source="{Binding Img}" />
                                </StackLayout>

                                <StackLayout Orientation="Vertical">
                                    <Label x:Name="myLabel" Text="ddddddd" IsVisible="false"/>
                                    <Label Text="{Binding Name}" />
                                    </StackLayout>
                            </StackLayout>      
                        </Grid>

                  </ViewCell>
                </DataTemplate>
              </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

And this is the code behind:

public EditOrderPage(string name)
{
    InitializeComponent();

    OrderDataModel order = GetOrder(name);
    myLabel.Text = "show this!";

    oName.Text = order.orderName; 
    ObservableCollection<ProductsDataModel> ProductsInList = order.products;
    countProducts.Text = "Tot Products: " + ProductsInList.Count.ToString(); 


    ObservableCollection<ProductsDataModel> all_products = ProductsDataModel.All;

    List<ProductsDataModel> myList= new List<ProductsDataModel>(ProductsInList);

    ...
    ...
    ...

    ProductList.ItemsSource = myList;
}

Any Idea?

Tagged:

Best Answer

Answers

  • StefaanAvonds.3725StefaanAvonds.3725 USMember ✭✭✭

    Hi @GiuseppeCristaudo

    You cannot get the name of the label located inside the ViewCell of a Listview. Why don't you use DataBinding like you are doing with the other label inside the ViewCell?

    What is the purpose of the label "myLabel"?

  • AsknetAsknet USMember ✭✭

    Hi StefaanAvonds.3725,

    the purpose of the label myLabel is to display different text depending on some conditions. I cannot use DataBinding because this is not a property depends directly on single product like:

    <Label Text="{Binding Name}" />

    What I need is, for example, to check if the single product (item of the Listview ProductList) is contained within a specific List and, in this case, show a Text rather then another.

  • AsknetAsknet USMember ✭✭

    Thank you StefaanAvonds.3725, you are right!

    I use the first solution, creating a new DataModel.

    just a clarification:

    I change the sintax for binding NOT from "{Binding Name}" to "{Binding MyDataModel.Name}" but

    from "{Binding Name}" to "{Binding propertyNameInNewDataModel.Name}"

    Many thanks!

  • SreeeeSreeee INMember ✭✭✭

    @Asknet
    @StefaanAvonds.3725
    I am also having this same issue. I didn't understand the solution you prefer.
    I want to show the label value initially(like count), it is working.

          <ListView x:Name="ListView1"  RowHeight="500">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
    
                <Label 
                    Text="{Binding likeCount}"
                    x:Name="likecount" 
                    Font="14" 
                    TextColor="Black"
                    HorizontalOptions="Start" 
                    VerticalOptions="Center"/>  
    
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    

    After like or unlike i want to change the label text(like count). For that i use the following code:

        If(like){
         likecount.Text = item.likeCount + 1;
         } else{
         likecount.Text = item.likeCount - 1;
         }
    

    Currently showing, The name likecount does not exist in the current context.

    Can you show how you create the datamodel?

    Please help me, Thanks in advance.

  • StefaanAvonds.3725StefaanAvonds.3725 USMember ✭✭✭

    You cannot access the Label-control since it's located inside the ViewCell of a ListView.

    A possible solution: bind the ItemsSource-property of your ListView to a collection of objects, for example LikeCountModel. This model should look like this:

    public class LikeCountModel : INotifyPropertyChanged
    {
        private int _likeCount;
    
        public int LikeCount
        {
            get => _likeCount;
            set => SetField(ref _likeCount, value);
        }
    
        public LikeCountModel()
        {
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected bool SetField<T>(ref T field, T value, [CallerMemberName]string propertyName = "")
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
            field = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            return true;
        }
    }
    

    Every time your property "LikeCount" changes its value, the INotifyPropertyChanged-event is triggered.

    Your ListView will have an ItemsSource equal to a collection of these objects; for example:

    <ListView ItemsSource="{Binding Path=MyLikeCountModels}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Label Text="{Binding Path=LikeCount}" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    And in your binding context:

    private ObservableCollection<LikeCountModel> _myLikeCountModels;
    
    public ObservableCollection<LikeCountModel> MyLikeCountModels
    {
        get => _myLikeCountModels;
        set => SetField(ref _myLikeCountModels, value);
    }
    

    Now the only thing that remains is to update the correct model in your collection and your Label will change depending on your action.

    MyLikeCountModels[index].LikeCount += 1;
    // or
    modelToUpdate.LikeCount += 1;
    

    When exactly is your "if (like) ..."-statement executed?

Sign In or Register to comment.