Problem with Binding and IsVisible

Hi there,

I am (obviously, regarding the question) new to this, so thanks in advance for any help! As I am trying my current best on this for hours now, I hope, someone can accelerate my learning curve :)

So, I have my XAML MainPage:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="cant post links"
             xmlns:x="cant post links"
             xmlns:local="clr-namespace:App.ViewModels"
             x:Class="App.ViewModels.MainPage">

    <ContentPage.BindingContext>
        <local:User/>
    </ContentPage.BindingContext>

    <StackLayout>
        <Label Text="Test"/>
        <ListView ItemsSource="{Binding Changes}"
                  x:Name="ChangesList"
                  HasUnevenRows="True"
                  Margin="40,80"
                  ItemTapped="ListView_ItemTapped">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label Text="{Binding Name}"/>
                            <Button Text="Details"
                                    IsVisible="{Binding IsVisible}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Text="Press to add" x:Name="addItem" Clicked="addItem_Clicked"/>
    </StackLayout>

</ContentPage>

I have a datamodel with the correponding attributes behind. When I leave the MainPage class constructor like the following:

public MainPage()
{
    InitializeComponent();
}

I see no list items.

So, first Question: I thought, based on the bindings, the app would automatically generate a User instance and assign it to the list? As I can see with the debugger, a User instance actually is generated and also assigned to the BindingContext, but the ChangesList.ItemsSource remains null.

Therefore, I changed the code of the constructor:

public MainPage()
        {
            InitializeComponent();
            var bc = BindingContext;
            var list = ChangesList.ItemsSource;
            ChangesList.ItemsSource = (bc as User).Changes;
        }

This lets me see a list with items when I compile and run the app. Also, I can add new items to the list via the code behind the 'addItem' Button. However: Nothing happens, when I tap an item. The code looks like follows:

        private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
        {
            var change = e.Item as Change;
            change.IsVisible = !change.IsVisible;
        }

and the Data methods look as follows:

        public bool IsVisible
        {
            get
            {
                return isVisible;
            }
            set
            {
                isVisible = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Change-IsVisible"));
            }
        }

Therefore the second question: Why does the Button not change its visibility status and become visible?

Thank you very much in advance!
Wolf

Answers

  • ManojkumarMaliManojkumarMali USMember ✭✭✭
    edited September 3

    Hi,

    Re-assign item list to ItemSource of ChangesList, after you change the visibility.

  • ColeXColeX Member, Xamarin Team Xamurai
    edited September 3

    PropertyChangedEventArgs should receive propertyName , you just need modify

    new PropertyChangedEventArgs("Change-IsVisible")
    

    to

    new PropertyChangedEventArgs("IsVisible")
    
  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I thought, based on the bindings, the app would automatically generate a User instance and assign it to the list?

    Clarification: Its not going to be assigned to the List. Why would it be?

        <ContentPage.BindingContext>
            <local:User/>
        </ContentPage.BindingContext>
    

    It will become the BindingContext for the Page - not the List. The ListView will inherit (and thus use) its Parent's BindingContext unless a new BindingContext is explicitly set. For your purpose in this little example it will basically have the same effect - but its important to understand the what is really happening. Its not assigned to the ListView. Its assigned to the Page and the ListView is just inheriting the use of it.

    <ListView ItemsSource="{Binding Changes}"

    This means the ListView is looking for a property on its BindingContext, called Changes - that should be some sort of ObservableCollection<change> - Do you have a Change class? Do you have a collection on your user called Changes? I don't see it in the code you shared.

    Just a guess... But it looks like you're trying to reverse-engineer an understanding of binding and MVVM from trying to make something from scratch. I'd suggest instead actually working through the many tutorials on the topic where you are guided in learning this complex topic and you build what the instructors lays out for you. Trying to build your own app from scratch while learning the concepts is never a good route.
    http://redpillxamarin.com/2018/03/12/2018-101-vs2017-new-solution/

    Free eBook on Xamarin Forms
    https://blogs.msdn.microsoft.com/microsoft_press/2016/03/31/free-ebook-creating-mobile-apps-with-xamarin-forms/

    And of course Xamarin University is really the way to go - even if you have 20 years of experience with XAML/MVVM (speaking from experience)

Sign In or Register to comment.