【问题标题】:Keep the collections in the list in MVVM将集合保存在 MVVM 的列表中
【发布时间】:2014-03-05 05:41:14
【问题描述】:

目前我在将集合保存在 mvvm 的列表中时遇到了麻烦,每次我离开并返回页面时,列表都会变空。我将如何处理这个问题?有人可以帮我弄这个吗? 该模型: 我还没有实现其他的,因为我无法将项目添加到列表中

 class CartData
        {
            public int Cakeprice { get; set; }
            public ImageSource ImagePath { get; set; }
            public string Caketype { get; set; }
            public string Cakename { get; set; }
            public int TotalItems { get; set; }

        }

视图模型:

class CartingDataSource : BindableBase
    {
public ObservableCollection<CartData> _cartData;

public ObservableCollection<CartData> CartData
        {

         get {
             return _cartData;
             }
        set {

                SetProperty(ref _cartData, value);
           }
        }
 private DelegateCommand _addItemCommand;
        public ICommand AddItemCommand
        {
            get
            {
                if (_addItemCommand == null)
                {
                    _addItemCommand = new DelegateCommand(AddToCart);
                }
                return _addItemCommand;
            }
        }

 public void AddToCart() {

            CartData.Add(new CartData { Cakename = "Black Forest", Cakeprice = 104 });
                   }

} 观点:

.....

 <Page.DataContext>
        <vm:CartingDataSource/>
    </Page.DataContext>
   ....
<ListView
            x:Name="itemListView"
            AutomationProperties.AutomationId="ItemsListView"
            AutomationProperties.Name="Items"
            TabIndex="1"
            Margin="-10,130,0,264"
            Padding="120,0,0,60"

            ItemsSource="{Binding cartData}"
            IsSwipeEnabled="False" Grid.RowSpan="2" ItemClick="itemListView_ItemClick" SelectionChanged="itemListView_SelectionChanged_1" IsItemClickEnabled="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="6">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60">
                            <Image Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Source="Assets/TempPic.jpg"/>
                        </Border>
                        <StackPanel Grid.Column="1" Margin="10,0,0,0">
                            <TextBlock Text="{Binding Cakename}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap" MaxHeight="40"/>
                            <TextBlock Text="{Binding Cakeprice}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="FrameworkElement">
                    <Setter Property="Margin" Value="0,0,0,10"/>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

【问题讨论】:

  • 您是否在代码中的某处重新实例化集合?
  • @cvraman 不,我没有重新实例化我的代码。这是我上一个问题中的完整代码:stackoverflow.com/questions/22163110/…
  • 您在 Prism 解决方案中使用的是哪个容器?是 MEF 还是 Unity?如果 Unity 是这种情况,您应该注意到容器不保留对 View 的引用,并且每次导航到它时它都会解析新实例。因此,当您离开 View 时,该实例将被释放,每次您导航回指定的 View 时都会获得一个带有空集合的新 View/ViewModel 实例。有关详细信息,请参阅管理依赖项的 MSDN Prism chapter

标签: c# xaml mvvm microsoft-metro prism


【解决方案1】:

您何时创建集合的实例?

我建议您将集合设为只读,并仅在需要时创建后备存储字段的实例。

public ObservableCollection<CartData> CartData
        {

         get {
                if( _cartData == null ) _cartData = new ObservableCollection<CartData> ();
                return _cartData;
             }
        set {

                SetProperty(ref _cartData, value);
           }
        }

【讨论】:

  • 但这给了我一个错误:“只读对这个项目无效”
  • 没关系。
  • 但这给了我一个错误:“只读对这个项目无效”
  • 尝试使用 ReadOnlyObservableCollection 。 stackoverflow.com/questions/6346948/… 基本思想是为应用程序的生命周期创建集合的单个实例。
  • @bit:不要像这样读/写属性。考虑以下代码:obj.CardData = null; Debug.Assert(obj.CardData == null)。断言将失败,因为 getter 忽略了有人从外部将此属性设置为 null。此外,您的回答并不能解决问题。
【解决方案2】:

根据您提供的信息,我可以理解您没有实例化 ObservableCollection CartData,但是看起来 CartData 被设置为 null。

由于有关问题的信息有限,我建议您使用 PRISM 的最佳功能之一 EventAggregator。它会解决你的问题。

EventAggregator 可以帮助您发布带有值的模型(CartData)并在需要时订阅它。

一些有用的链接

Trying to understand the event aggregator pattern

http://msdn.microsoft.com/en-us/library/ff921122.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 2013-11-09
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多