Xamarin列表〈>未更新UI

gmol1639  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(148)

I wanted to try toggling a series of StackLayout's IsVisible property using a list of boolean. To better elaborate, here are my codes:

View

<ContentPage.Content>
        <StackLayout>
            <StackLayout IsVisible="{Binding pageVisible[0]}">
                <Label Text="Page 1"/>
                <Button Text="Next"
                        Command="{Binding ToNextCommand}"
                        CommandParameter="{Binding currentPage}"/>
            </StackLayout>
            <StackLayout IsVisible="{Binding pageVisible[1]}">
                <Label Text="Page 2"/>
                <Button Text="Next"
                        Command="{Binding ToNextCommand}"
                        CommandParameter="{Binding currentPage}"/>
            </StackLayout>
            <StackLayout IsVisible="{Binding pageVisible[2]}">
               <Label Text="Page 3"/>
               <Button Text="Next"
                       Command="{Binding ToNextCommand}"
                       CommandParameter="{Binding currentPage}"/>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>

View Model

private List<bool> _pageVisible;
        public List<bool> pageVisible 
        { 
            get => _pageVisible;
            set
            {
                _pageVisible = value;
                OnPropertyChanged();
            }
        }
        public ProfileCompletionViewModel()
        {
            pageVisible = new List<bool>();
            pageVisible.Add(true); //to make the first stacklayout visible

            for (var i = 0; i < 2; i++)
            {
                pageVisible.Add(false);
            }
        }
        public ICommand ToNextCommand { get; }
        private int _currentPage = 0;
        public int currentPage
        {
            get => _currentPage;
            set => SetProperty(ref _currentPage, value);
        }
        private async Task ToNextFunc()
        {
            for (var i = 0; i < 3; i++)
                pageVisible[i] = false; //Set all to false
            pageVisible[_currentPage + 1] = true;
            currentPage += 1;
        }
    }

The list is updating well when I clicked 'Next' (I found out using breakpoints). But the View is not updating despite having OnPropertyChange() on the List. Is there something wrong in my codes? T_T
Thank you in advance

a14dhokn

a14dhokn1#

我明白了,我只是试了一下它是否能用最少的代码行工作。我想我需要给每个属性一个单独的属性。
是的,您可以为每个属性定义几个单独的变量,但是您也可以为列表的项创建一个模型并实现接口INotifyPropertyChanged
我创建了一个demo来模拟这个函数,它在我这边工作正常。你可以参考下面的代码:
1.为列表项创建一个类Item

    • 项目. cs**
public class Item: INotifyPropertyChanged 
    {
        private bool _pageVisible;
        public bool PageVisible
        {
            set { SetProperty(ref _pageVisible, value); }
            get { return _pageVisible; }
        }

        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    • 我的视图模型. cs**
public class MyViewModel: INotifyPropertyChanged 
    {

        public  List<Item> pageVisibleList { get; set; }
        public MyViewModel()
        {
            pageVisibleList = new List<Item>();
            pageVisibleList.Add( new Item { PageVisible = true}); //to make the first stacklayout visible

            for (var i = 0; i < 2; i++)
            {
                pageVisibleList.Add(new Item { PageVisible = false });
            }

        }
        public ICommand ToNextCommand => new Command(ToNextFunction);

        private void ToNextFunction()
        {
            for (var i = 0; i < 3; i++)
                pageVisibleList[i].PageVisible = false; //Set all to false

            if (_currentPage < 2)
            {
                pageVisibleList[_currentPage + 1].PageVisible= true;
            }
            else {
                _currentPage = 0;
                pageVisibleList[0].PageVisible = true;
            }
            currentPage += 1;
        }

        private int _currentPage = 0;
        public int currentPage
        {
            get => _currentPage;
            set => SetProperty(ref _currentPage, value);
        }

        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    • 测试页面. xaml.cs**
<?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:app1109="clr-namespace:App1109"
             x:Class="App1109.TestPage">

    <ContentPage.BindingContext>
        <app1109:MyViewModel></app1109:MyViewModel>
    </ContentPage.BindingContext>
    <ContentPage.Content>
        <StackLayout>
            <StackLayout IsVisible="{Binding pageVisibleList[0].PageVisible}">
                <Label Text="Page 1"/>
                <Button Text="Next --> Button 1"
                        Command="{Binding ToNextCommand}"
                        />
            </StackLayout>
            <StackLayout IsVisible="{Binding pageVisibleList[1].PageVisible}">
                <Label Text="Page 2"/>
                <Button Text="Next  --> Button 2"
                        Command="{Binding ToNextCommand}"
                        />
            </StackLayout>
            <StackLayout IsVisible="{Binding pageVisibleList[2].PageVisible}">
                <Label Text="Page 3"/>
                <Button Text="Next --> Button 3"
                       Command="{Binding ToNextCommand}"
                       />
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

相关问题