How to activate an existing order details view in StockTraderRI ?

Topics: Prism v2 - Silverlight 4
May 17, 2013 at 10:41 PM
Background:
  1. With StockTraderRI demo application when you select an action in the PositionSummary view an OrderCompositeView is activated by the OrderController. The only information displayed on the view is the symbol, ie STOCK01. This is done via TransactionInfo object.
  2. There is a binding between OrderDetailsViewModel to OrderCompositeView via this property:
    public object OrderDetails
    {
        get { return this.orderDetailsViewModel; }
    }
    
  3. When the OrderCompositeView is displayed the entry is blank and awaits user input before it can be processed.
My question:
Let's suppose if by clicking the PositionSummaryItem I want to display details of this item in my OrderCompositeView - so it's not going to be a new entry but an existing one. How do I pass the TransactionInfo details to my OrderDetailsViewModel?

This is where the concrete class gets injected in the OrderCompositeViewModel:
    [ImportingConstructor]
    public OrderCompositeViewModel(IOrderDetailsViewModel orderDetailsViewModel)
    {
        this.orderDetailsViewModel = orderDetailsViewModel;
        this.orderDetailsViewModel.CloseViewRequested += _orderPresenter_CloseViewRequested;
    }
How do I pass the tickerSymbol parameter to the OrderDetailsViewModel in order to activate the OrderDetailsView with data from STOCK01 object ?

In the StartOrder method of the OrderController the TransactionInfo is passed to the OrderCompositeViewModel through this property injection:
        var orderCompositeViewModel = ServiceLocator.Current.GetInstance<IOrderCompositeViewModel>();

        orderCompositeViewModel.TransactionInfo = new TransactionInfo(tickerSymbol, transactionType);
This very tickerSymbol needs to be passed down to the constructor of the OrderDetailsViewModel as well. How do I do that? At what point in OrderDetailsViewModel do I retrieve the new record using the tickerSymbol? Do I use the ServiceLocator as in ServiceLocator.Current.GetInstance<IOrderDetailsViewModel>(); ? How is the ticker Symbol passed ?

I know I could I start newing things up and create unnecessary coupling. I'm very keen to do this the right way. Any help would be greatly appreciated.
May 20, 2013 at 7:49 PM
Hi,

I'm not sure if I understand what you are trying to achieve. If what you want is to simply set the TransactionInfo from your orderDetailsViewModel, this is already being done in the code you provided before, since the property TransactionInfo from your orderCompositeViewModel will also set the same TransactionInfo for the orderDetailsViewModel, which comes through Dependency Injection in the OrderCompositeViewModel constructor. So if you want to pass tickerSymbol to your orderDetailsViewModel, you will just need to set the TransactionInfo using that tickerSymbol to your orderCompositeViewModel.
orderCompositeViewModel.TransactionInfo = new TransactionInfo(tickerSymbol, transactionType);
If you want to use TransactionInfo in a way that you can react and show details from an item, you could use a new TransactionType, since TransactionType is defined as:
public enum TransactionType
{
    Buy,
    Sell
}
If this doesn't help you or we misunderstood your scenario, it would be helpful if you could provide us more information about what you are trying to achieve.

Regards.

Federico Martinez
http://blogs.southworks.net/fmartinez
May 23, 2013 at 10:19 AM
Edited May 23, 2013 at 10:50 AM
Thank you for your reply Federico. This is the answer I was after.

This is what I'll be doing which is along the lines of your suggestion. (Instead of OrderDetails I have a class called JournalEntryDetails).
    public TransactionInfo TransactionInfo
    {
        get { return this.JournalEntryDetailsViewModel.TransactionInfo; }
        set
        {
            SetTransactionInfo(value);

            // 
            JournalEntry journalEntry =
                this.journalEntryService.GetJournalEntry(value.JournalEntryId);
            this.JournalEntryDetailsViewModel.HeaderText = journalEntry.HeaderText;
            this.JournalEntryDetailsViewModel.BodyText = journalEntry.BodyText;
        }
    }
My plan is the following. When the TransactionInfo property is set I will:
  1. Create a reference to a new JournalEntry (or OrderDetails) record from JournalEntryCompositeViewModel using the transaction info. In my case it is the JournalEntryId (or TickerSymbol in StockTraderRI).
    2.Set the values in the JournalEntryDetailsViewModel (or OrderDetailsViewModel)
May 26, 2013 at 10:53 PM
Edited May 27, 2013 at 6:02 PM
Hi Federico,

I wonder if you could help me out with this one.

FYI: For my demo, I have renamed OrderEntryDetails with JournalEntryDetails. It has the same functionality as in the StockTraderRI demo app.

This is what I've done. In the JournalEntryDetailsViewModel (or OrderEntryDetailsViewModel) I added the following code to TransactionInfo property:
    public TransactionInfo TransactionInfo
    {
        get { return this.transactionInfo; }
        set
        {
            this.transactionInfo = value;
            this.RaisePropertyChanged(() => this.TransactionType);
            this.RaisePropertyChanged(() => this.JournalEntryId);

            // refresh data

            JournalEntry journalEntry = journalEntriesService.GetJournalEntry(value.JournalEntryId);
            this.HeaderText = journalEntry.HeaderText;
            this.BodyText = journalEntry.BodyText;
      }
    }
The idea here is that when transaction info is set in the OrderDetailsViewModel I obtain the existing record from the XML file using the JournalEntryId from the TransactionInfo object.
I subsequently load two properties HeaderText and BodyText with the values from the XML file.

The retrieval of the JournalEntryDetails via the journalEntiresService class works fine. The problem is that values for HeaderText and BodyText still doesn't show on the JournalEntryDetails view. As a matter of fact I seem to be getting a stack overflow exception when attempting to assign a value to this.HeaderText.

Is there a binding problem here? Any help would be greatly appreciated.
Developer
May 27, 2013 at 6:08 PM
Hi,

In the code snippet you posted it seems that you are not raising the PropertyChanged event (using the RaisePropertyChanged method) for the HeaderText and BodyText properties, unless they are being raised in their corresponding setters. If that is not the case, please try adding a RaisePropertyChanged invocation for both properties at the end of the setter.

Take into account that when you change the value of a property, you need to raise the aforementioned event to inform the view of this change. If not, the view will keep showing the older values.

Regarding the "stack overflow" part, such a thing can happen if a property is accessing itself in its setter or getter. For example:
private string headerText;

public string HeaderText
{
    get { return this.headerText; }    // We return the value of the headerText attribute, OK.
    set { this.HeaderText = value; }  // We made a typo and as a result the code access this property again instead of the attribute, resulting in a stack overflow.
}
I hope this helps,

Damian Cherubini
http://blogs.southworks.net/dcherubini
May 30, 2013 at 12:47 AM
Hi Damian,

Thank you very much for your help.

I am using the PropertyChanged events in the property.

You were correct about the issue with the stack overflow. I've fixed that.

I'm encountering some composition errors at the moment. I'll fix those before I can tackle my original problem.

Again, I'm very grateful for the help.