0

对于数据项列表,我有以下 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 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 属性发生变化,并将其反映在视图中。我尽我所能,但仍然无法实现。有什么我想念的吗?任何帮助表示赞赏

4

2 回答 2

0

我还注意到 LongListSelector 和 ObservableCollection 的一些问题。我把它贴在这里:
长列表选择器可观察集合和可视树 - 问题?

请检查您的项目,如下所示:使用返回按钮离开页面,然后使用 LLS 重新进入页面 - 如果正确显示,则意味着我们有同样的问题,我认为这是 LLS 的问题,我们必须等待 WP 8.1。我假设 LLS 没有正确更新(VisualTree 没有改变),因为当我使用普通的 ListBox 时,一切正常。

尝试使用 ListBox (因为你没有分组):

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

如果您没有看到更改,您可以尝试调用(在我的项目中,该功能不适用于 LLS,但使用 LisBox 可以正常工作):

Port_SummaryList.UpdateLayout();
于 2013-11-03T06:49:00.587 回答
0

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

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

我刚遇到一个情况,它的Mode行为就像默认为Mode=OneTime. 明确设置后Mode=OneWay,我的数据更改开始显示。此处暗示的 BindingMode 枚举文档Mode=OneWay是隐含的。最近的经验表明,情况可能并非总是如此。

于 2014-08-31T16:44:28.723 回答