データ項目のリストには、次の XAML があります。
<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<>」は、このSO投稿からのものです。
クラス「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 プロパティの変更を確認し、それをビューに反映することです。私はできる限りのことを試みましたが、それでもそれを達成することはできません。不足しているものはありますか?どんな助けでも大歓迎です