2013-11-03 53 views
0

我已经为数据项的列表下面的XAML代码:WP8的ObservableCollection项目更新没有反映在视图

<phone:LongListSelector x:Name="Port_SummaryList" ItemsSource="{Binding PortList}" ItemTemplate="{StaticResource PortfolioDataTemplate}"/> 

模板被定义为这样的:

<phone:PhoneApplicationPage.Resources> 
    <DataTemplate x:Key="PortfolioDataTemplate"> 
     <Grid d:DesignHeight="91.5" d:DesignWidth="439.875" Height="82"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="31*"/> 
       <ColumnDefinition Width="19*"/> 
       <ColumnDefinition Width="19*"/> 
       <ColumnDefinition Width="19*"/> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="15*"/> 
       <RowDefinition Height="15*"/> 
       <RowDefinition Height="15*"/> 
      </Grid.RowDefinitions> 
      <TextBlock x:Name="PortfolioName" HorizontalAlignment="Left" Height="92" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top" Width="155" Grid.RowSpan="2" Margin="0,0,0,-10"/> 
      <TextBlock x:Name="NAV" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Height="31" TextWrapping="Wrap" Text="{Binding NAV, StringFormat='{}{0:C}'}" VerticalAlignment="Top" Width="95" Margin="0,-1,0,0"/> 
      <TextBlock x:Name="CostBasis" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Height="30" TextWrapping="Wrap" Text="{Binding Cost,StringFormat='{}{0:C}'}" VerticalAlignment="Top" Width="95" />        
     </Grid> 
    </DataTemplate> 
</phone:PhoneApplicationPage.Resources> 

,并在我的ViewModel我有此:

private TrulyObservableCollection<PortfolioModel> _PortList; 
    public TrulyObservableCollection<PortfolioModel> PortList 
    { 
     get { return _PortList; } 
     set 
     { 
      _PortList = value; 
      _PortList.CollectionChanged += _PortList_CollectionChanged; 
      RaisePropertyChanged("PortList"); 
     } 
    } 

    void _PortList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     RaisePropertyChanged("PortList"); 
    } 

类 “TrulyObservableCollection <>” 是从this SO post

类“PortfolioModel”的定义是这样的:

public class PortfolioModel : INotifyPropertyChanged 
{ 
    public string Name { get; set; } 
    public DateTime Created { get; set; } 
    public int Id { get; set; } 

    public TrulyObservableCollection<CashModel> Cashflow; 
    public TrulyObservableCollection<HoldingModel> Positions; 

    public float Cost 
    { 
     get 
     { 
      float total_cost = 0.0f; 
      foreach (HoldingModel holding in Positions) 
      { 
       total_cost += holding.Share * holding.CostBasis; 
      } 
      return total_cost; 
     } 
     private set { ;} 
    } 
    //Numbers that are calculated with other variables, listed here for databinding purposes 
    public float NAV 
    { 
     get 
     { 
      float acc = 0.0f; 
      foreach (HoldingModel hm in Positions) 
      { 
       acc += hm.CurrentPrice * hm.Share; 
      } 
      foreach (CashModel cm in Cashflow) 
      { 
       acc += cm.Amount; 
      } 
      return acc; 
     } 
     set { ;} 
    } 
    public float DailyPercent { get; set; } 
    public float OverallPercent { get; set; } 

    public PortfolioModel() 
    { 
     Cashflow = new TrulyObservableCollection<CashModel>(); 
     Cashflow.CollectionChanged += Cashflow_CollectionChanged; 
     Positions = new TrulyObservableCollection<HoldingModel>(); 
     Positions.CollectionChanged += Positions_CollectionChanged; 
    } 

    void Positions_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     NotifyPropertyChanged("Positions"); 
     NotifyPropertyChanged("NAV"); 
    }   
    void Cashflow_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     NotifyPropertyChanged("Cashflow"); 
     NotifyPropertyChanged("NAV"); 
    }  


    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(String propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (null != handler) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

类“HoldingModel”的定义是这样的:

public class HoldingModel : INotifyPropertyChanged 
{ 
    private string _Ticker; 
    public string Ticker 
    { 
     get { return _Ticker; } 
     set { if (value != _Ticker) { _Ticker = value; NotifyPropertyChanged("Ticker"); } } 
    } 

    private string _CompanyName; 
    public string CompanyName 
    { 
     get { return _CompanyName; } 
     set { if (value != _CompanyName) { _CompanyName = value; NotifyPropertyChanged("CompanyName"); } } 
    } 

    private int _Share; 
    public int Share 
    { 
     get { return _Share; } 
     set { if (value != _Share) { _Share = value; NotifyPropertyChanged("Share"); } } 
    } //negative means short 

    public string LongShort 
    { 
     get { if (Share > 0) return "LONG"; else return "SHORT"; } 
    } 

    private float _Value; 
    public float Value 
    { 
     get { return _Value; } 
     set { if (value != _Value) { _Value = value; NotifyPropertyChanged("Value"); } } 
    } 

    public float Cost 
    { 
     get { return Share * CostBasis; } 
     set { ;} 
    } 

    private float _CostBasis; 
    public float CostBasis 
    { 
     get { return _CostBasis; } 
     set { if (value != _CostBasis) { _CostBasis = value; NotifyPropertyChanged("CostBasis"); } } 
    } 

    private float _RealizedGain; 
    public float RealizedGain 
    { 
     get { return _RealizedGain; } 
     set { _RealizedGain = value; NotifyPropertyChanged("RealizedGain"); } 
    } 

    private float _CurrentPrice; 
    public float CurrentPrice 
    { 
     get { return _CurrentPrice; } 
     set 
     { 
      _CurrentPrice = value; 
      NotifyPropertyChanged("CurrentPrice"); 
     } 
    } 

    private float _CurrentChange; 
    public float CurrentChange 
    { 
     get { return _CurrentChange; } 
     set { _CurrentChange = value; NotifyPropertyChanged("CurrentChange"); } 
    } 

    ObservableCollection<TradeModel> Trades; 

    public HoldingModel() 
    { 
     Trades = new ObservableCollection<TradeModel>(); 
    } 

    public void AddTrade(TradeModel trade) 
    { 
     //Order can't change, since RealizedGain relies on CostBasis and Share, CostBasis relies on Share 
     UpdateRealizedGain(trade); 
     UpdateCostBasis(trade); 
     Share += trade.Share; 
     trade.PropertyChanged += PropertyChanged; 
     Trades.Add(trade); 
    } 
    private void UpdateCostBasis(TradeModel trade) 
    { 
     if (trade.Share + Share == 0) 
     { 
      CostBasis = 0; 
      return; 
     } 
     float cost = CostBasis * Share; 
     cost += trade.Price * trade.Share; 
     CostBasis = cost/(Share + trade.Share); 
    } 
    private void UpdateRealizedGain(TradeModel trade) 
    { 
     if (trade.Share * Share > 0) return; //No realized gain on add-on 
     if (Math.Abs(trade.Share) > Math.Abs(Share)) 
     { 
      RealizedGain += Share * (trade.Price - CostBasis); 
     } 
     else 
     { 
      RealizedGain += trade.Share * (trade.Price - CostBasis); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(String propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     //Debug.WriteLine("symbol_user got property {0} changed, bubbling up", propertyName); 
     if (null != handler) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

我想要做的是,我每次更新HoldingModel中的CurrentPrice属性,我想看到PortfolioModel中的NAV属性发生变化,并反映在视图中。我尽我所能,但仍然无法实现。有什么我失踪的?任何帮助表示赞赏

回答

0

我也注意到LongListSelector和ObservableCollection的一些问题。我已经发布在这里:
Long List Selector Observable Collection and Visual Tree - problems?

请检查您的项目是这样的:离开页面后退按钮,并重新进入页面的LLS - 如果它被正确显示,这意味着我们有同样的问题,我认为这是LLS的问题,我们必须等待WP 8.1。我认为LLS没有正确更新(VisualTree不会更改),因为当我使用普通的ListBox时,一切都很完美。

尝试使用列表框(因为你没有做分组):

<ListBox x:Name="Port_SummaryList" ItemsSource="{Binding PortList}" ItemTemplate="{StaticResource PortfolioDataTemplate}"/> 

如果您没有看到变化,你可以尝试调用(在我的项目,功能不与LLS但worj LisBox工作正常):

Port_SummaryList.UpdateLayout(); 
+0

感谢您的帮助,但它似乎不起作用 – hxdai

0

尝试在NAV绑定中明确指定Mode=OneWay

Text="{Binding NAV, Mode=OneWay, StringFormat='{}{0:C}'}" 

我只是其中Mode表现就像是默认为Mode=OneTime的情况下。在明确设置Mode=OneWay后,我的数据更改开始显示。 BindingMode枚举文档here暗示Mode=OneWay暗含。最近的经验表明,情况并非总是如此。

相关问题