ObservableCollection没有更新,我做错了什么?

3

我在我的Xamarin.Forms应用程序中遇到了ObservableCollection问题。

我能够添加值(我可以在调试器中读取它们),但是视图不会更新。

到目前为止,我尝试了很多方法,但是似乎没有解决这个问题。

希望您能帮忙:)

这是我的代码:

private ObservableCollection<Transaction> transactions = new ObservableCollection<Transaction>();
public ObservableCollection<Transaction> Transactions
    {
        get { return transactions; }
        set
        {
            transactions = value;
            OnNotifyPropertyChanged();
        }
    }
public class Transaction:BaseViewModel
{
    private string name = null;
    private string price = null;
    private double numPrice = 0;
    private string date = null;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            OnNotifyPropertyChanged();
            name = value;
        }
    }
    public string Price
    {
        get
        {
            return price;
        }
        set
        {
            OnNotifyPropertyChanged();
            price = value;
        }
    }
    public double NumPrice
    {
        get
        {
            return numPrice;
        }
        set
        {
            OnNotifyPropertyChanged();
            numPrice = value;
        }
    }
    public string DateTime
    {
        get
        {
            return date;
        }
        set
        {
            OnNotifyPropertyChanged();
            date = value;
        }
    }
}

我的BaseViewModel:

public class BaseViewModel : INotifyPropertyChanged
{
    
    protected BaseViewModel()
    {

    }

    #region Events
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(memberName));
        }
    }
}

在XAML中:
<ScrollView>
        <StackLayout BindableLayout.ItemsSource="{Binding Transactions}">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <Frame BackgroundColor="#4D4D4D" CornerRadius="10">
                        <StackLayout Orientation="Horizontal">
                            <StackLayout>
                                <Label Text="{Binding Name}"/>
                                <Label Text="{Binding DateTime}"/>
                            </StackLayout>
                            <Label Text="{Binding Price}" FontSize="20"
                                   HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand" Margin="0,0,10,0" />
                        </StackLayout>
                    </Frame>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </ScrollView>

感谢您提前帮忙!
编辑: 这是我更新集合的方法:
public void AddTransaction(string name, double price, DateTime dateTime)
    {
        Transactions.Add(new Transaction()
        {
            Name = name,
            Price = ($"-{price}€".Replace('.',',')),
            NumPrice = price,
            DateTime = dateTime.ToString("dd.MM.yyyy")
        });

    }

1
你在哪里更新集合?没有这个信息,很难知道出了什么问题。到底是什么出了问题?有一件事肯定是错的,就是在改变值之前调用 OnPropertyChanged。它必须在设置值之后才能调用。 - Julian
一个问题,为什么你在StackLayout中使用BindableLayout而不是ListView? - Julian
2个回答

0

请尝试以下方法,看看是否有效:

<ScrollView>
        <ListView ItemsSource="{Binding Transactions}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Frame BackgroundColor="#4D4D4D" CornerRadius="10">
                        <StackLayout Orientation="Horizontal">
                            <StackLayout>
                                <Label Text="{Binding Name}"/>
                                <Label Text="{Binding DateTime}"/>
                            </StackLayout>
                            <Label Text="{Binding Price}" FontSize="20"
                                   HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand" Margin="0,0,10,0" />
                        </StackLayout>
                    </Frame>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ScrollView>

如果需要,您也可以使用CollectionView来替换示例中的ListView

重要提示

不要忘记在所有属性设置器中更改顺序,例如:

public string Name
    {
        get
        {
            return name;
        }
        set
        {
            if(name == value) return;
            name = value;
            OnNotifyPropertyChanged();
        }
    }

替代方案

为了确保您的视图得到更新,您可以在添加项目时调用集合上的OnNotifyPropertyChanged()方法:

public void AddTransaction(string name, double price, DateTime dateTime)
    {
        Transactions.Add(new Transaction()
        {
            Name = name,
            Price = ($"-{price}€".Replace('.',',')),
            NumPrice = price,
            DateTime = dateTime.ToString("dd.MM.yyyy")
        });
        OnNotifyPropertyChanged(nameof(Transactions));
    }

从技术上讲,在ObservableCollection上不应该需要这样做,但问题可能与在您的示例中附加到StackLayout的BindableLayout有关。


0

你可能在代码片段中缺少相关代码,但我猜测你是替换整个集合而不是更新它。从Transactions属性中删除getter,并确保成员transactions是只读的。"Observable"与集合的内容有关,而不是实例本身。


这里,集合的setter引发了PropertyChanged事件,因此替换集合应该可以正常工作。这可能与BindableLayout有关。 - Julian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接