在Xamarin&amp ;;中绑定ObservableCollection Listview时不刷新Spesific标签MVVM

时间:2018-06-15 18:45:42

标签: c# xamarin xamarin.forms binding observablecollection

public class Zicker : INotifyPropertyChanged
{
    public class MyClass
    {
        public string HeyName { get; set; }
        public string HeySurname { get; set; }
        public int HeyAge { get; set; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged([CallerMemberName] string name = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

    private ObservableCollection<MyClass> _yourList = new ObservableCollection<MyClass>();
    public ObservableCollection<MyClass> YourList
    {
        get
        {
            return _yourList;
        }
        set
        {
            _yourList = value;
            RaisePropertyChanged("YourList");
            RaisePropertyChanged("BindMeLabel");
        }
    }

    public int BindMeLabel
    {
        get { return _yourList.Sum(a => a.HeyAge); }
    }

    public void WonCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        RaisePropertyChanged("BindMeLabel");
    }

    public List<string> heresamplenames = new List<string> { "Mohamed", "Zaran", "Ivan" };
    public List<string> heresamplesurnames = new List<string> { "Pakou", "Simmone", "Zagoev" };
    public List<int> heresampleages = new List<int> { 17,33,50 };

    public Zicker()
    {
        ObservableCollection<MyClass> vs = new ObservableCollection<MyClass>();
        for (int i = 0; i < 3; i++)
        { vs.Add(new MyClass { HeyName = heresamplenames[i], HeySurname = heresamplesurnames[i], HeyAge = heresampleages[i] }); }
        YourList = vs; YourList.CollectionChanged += WonCollectionChanged;
    }
}

<ContentPage.Content>
    <StackLayout Orientation="Vertical" HorizontalOptions="Center" VerticalOptions="Center">
        <ContentView HorizontalOptions="Fill" VerticalOptions="Fill">
            <ListView HorizontalOptions="Center" VerticalOptions="Center" HasUnevenRows="True" ItemsSource="{Binding YourList}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="1*"></ColumnDefinition>
                                        <ColumnDefinition Width="1*"></ColumnDefinition>
                                        <ColumnDefinition Width="1*"></ColumnDefinition>
                                    </Grid.ColumnDefinitions>
                                    <Label HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding Path=HeyName}" Grid.Column="0" FontSize="12" TextColor="Black"></Label>
                                    <Label HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="{Binding Path=HeySurname}" FontSize="12" TextColor="Black" Grid.Column="1"/>
                                    <Entry HorizontalTextAlignment="Center" VerticalOptions="Center" Text="{Binding Path=HeyAge}" FontSize="12" Keyboard="Numeric" TextColor="Black" Grid.Column="2"/>
                                </Grid>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </ContentView>
        <Label Text="{Binding BindMeLabel}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" FontSize="40" TextColor="Black"></Label>
    </StackLayout>
</ContentPage.Content>

        public MainPage()
    {
        InitializeComponent();
        BindingContext = new Zicker();
    }

我的问题:在此列表中,有三个名称,姓氏和年龄。在底部,还有一个标签,应该显示为Ages集合的总和。

当UI启动时,Label运行良好。但是,如果我尝试更改任何Ages条目,则绑定标签存在很大问题。

我想使用MVVM结构,但由于这个问题,标签绑定才起作​​用。

1 个答案:

答案 0 :(得分:0)

如果要更新HeyName属性,则绑定不会更新,因为类MyClass未实现INotifyPropertyChanged

尝试使用以下代码替换MyClass类:

public class MyClass : INotifyPropertyChanged
{
    private string name;
    private string surname;
    private int age;

    public string HeyName
    {
        get => name;
        set
        {
            name = value;
            RaisePropertyChanged("HeyName");
        }
    }

    public string HeySurname
    {
        get => surname;
        set
        {
            surname = value;
            RaisePropertyChanged("HeySurname");
        }
    }

    public int HeyAge
    {
        get => age;
        set
        {
            age = value;
            RaisePropertyChanged("HeyAge");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged([CallerMemberName] string name = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

修改

很抱歉,更新CollectionChanged属性时未调用HeyAge,因为只有在更改集合时才会调用OnAgeChanged,但是当某个属性更改时,不是集合中的项目发生了变化。

尝试将MyClass事件添加到课程HeyAge中,并在public class MyClass : INotifyPropertyChanged { public event EventHandler OnAgeChanged; public int HeyAge { get => age; set { age = value; RaisePropertyChanged("HeyAge"); OnAgeChanged?.Invoke(this, EventArgs.Empty); } } ... ... 属性更改时调用它:

MyClass

然后,当您将新的ViewModel对象添加到集合中时,请在public Zicker() { ObservableCollection<MyClass> vs = new ObservableCollection<MyClass>(); for (int i = 0; i < 3; i++) { var test = new MyClass() { HeyName = heresamplenames[i], HeySurname = heresamplesurnames[i], HeyAge = heresampleages[i], }; test.OnAgeChanged += Test_OnAgeChanged; vs.Add(test); } YourList = vs; YourList.CollectionChanged += WonCollectionChanged; } private void Test_OnAgeChanged(object sender, EventArgs e) { RaisePropertyChanged("BindMeLabel"); } 中注册该事件,如下所示:

WonCollectionChanged

请注意,不再需要vs。 另请注意,不需要变量YourList,您可以直接使用<controls:ImageEx Name="ImageExControl" IsCacheEnabled="True" PlaceholderSource="/assets/thumbnails/thumbnails.png" Source="/assets/bigPicture.png"/> 对象。