}// ActiveGridUpdateGroup() // // // /// <summary> /// Update the cells and flash. /// </summary> /// <param name="rowName"></param> /// <param name="columnName"></param> /// <param name="newValue1"></param> /// <param name="isFlash"></param> private void UpdateActiveGridCell(string rowName, string columnName, object newValue1, bool isFlash) { string keyCell = GetCellKey(rowName, columnName); Decimal newValue; if (!Decimal.TryParse(newValue1.ToString(), out newValue)) { return; } SKACERO.ActiveRow.ActiveCell aCell = this.activeGrid1.FindCell(keyCell); if (aCell != null) { decimal oldValue = aCell.DecimalValue; aCell.DecimalValue = newValue; // Set fore colors if (newValue >= 0) { aCell.ForeColor = Color.Blue; } else if (newValue < 0) { aCell.ForeColor = Color.Red; } // Flash if (isFlash) { if (newValue > oldValue) { aCell.FlashBackColor = Color.Blue; //aCell.FlashPreText = "▲"; //aCell.FlashPostText = String.Empty; } else if (newValue < oldValue) { aCell.FlashBackColor = Color.Red; //aCell.FlashPreText = "▼"; //aCell.FlashPostText = String.Empty; } else { //aCell.FlashBackColor = Color.White; //aCell.FlashPreText = String.Empty; //aCell.FlashPostText = String.Empty; } } } }//UpdateActiveGridCell()
} //FindNewProperties() // // // // private void AddRows() { // Assume that we add all Fills one for each row, in order of their listing. int rowID = activeGrid1.Items.Count; this.activeGrid1.SuspendLayout(); while (rowID < m_Fills.Count) { // Create a new row SKACERO.ActiveRow aRow = new SKACERO.ActiveRow(); aRow.Name = rowID.ToString(); aRow.Text = rowID.ToString(); for (int i = 1; i < this.activeGrid1.Columns.Count; i++) { SKACERO.ActiveRow.ActiveCell cell = new SKACERO.ActiveRow.ActiveCell(aRow, String.Empty); cell.Name = String.Format("{0}_{1}", rowID, this.activeGrid1.Columns[i].Name); cell.DecimalValue = Decimal.Zero; cell.PreTextFont = new Font("Arial", cell.Font.Size); cell.PostTextFont = new Font("Arial", cell.Font.Size); aRow.SubItems.Add(cell); } // // Update values // for (int i = 0; i < m_PropertyNames.Count; ++i) { string propertyName = m_PropertyNames[i]; object o = m_Fills[rowID]; PropertyInfo propertyInfo = m_Fills[rowID].GetType().GetProperty(propertyName); //if (propertyInfo == null && m_Fills[rowID].FillDetails!=null) //{ // o = m_Fills[rowID].FillDetails; // propertyInfo = o.GetType().GetProperty(propertyName); // Property may belong to FillDetails. //} if (o != null && propertyInfo != null) { object value = propertyInfo.GetValue(o); string cellName = String.Format("{0}_{1}", rowID, propertyName); SKACERO.ActiveRow.ActiveCell cell = aRow.SubItems[cellName]; cell.Text = string.Format(m_PropertyFormat[i], value); } } // this.activeGrid1.Items.Add(aRow); rowID++; } this.activeGrid1.ResumeLayout(); }//
/// <summary> /// Creates the rows in the data-grid /// </summary> private void PopulateRows() { // This is essential as it will prevent the 'flashing' functionality // from being triggered while the grid is being initialised. this.lvBalances.SuspendLayout(); // Create a list to hold all of the row items. List <SKACERO.ActiveRow> items = new List <SKACERO.ActiveRow>(20); foreach (string ccy in this.currencies) { // Create a new row. SKACERO.ActiveRow item = new SKACERO.ActiveRow(); item.Text = ccy; item.Name = ccy; // Add the cells to the row, one for each column. // N.B. Starting from column ONE not column ZERO as this is // reserved for the row header. for (int i = 1; i < this.lvBalances.Columns.Count; i++) { SKACERO.ActiveRow.ActiveCell cell = new SKACERO.ActiveRow.ActiveCell(item, String.Empty); cell.Name = String.Format("{0}_{1}", ccy, this.lvBalances.Columns[i].Name); cell.DecimalValue = Decimal.Zero; cell.PreTextFont = new Font("Arial", cell.Font.Size); cell.PostTextFont = new Font("Arial", cell.Font.Size); item.SubItems.Add(cell); } items.Add(item); } // Add all of the rows to the list view. this.lvBalances.Items.AddRange(items.ToArray()); this.lvBalances.ResumeLayout(); }
/// <summary> /// Handles changes to an individual cell within the grid /// </summary> /// <param name="e"></param> private void CellUpdate(CellUpdateEventArgs e) { lock (syncRoot) { try { // There are three options for locating the cell we wish to update. // OPTION 1 // In this simulation, the data-feed generates a random cell based on // column-index and row-index. This makes life very easy when locating // the cell we need to update but it's not very realistic in a real-world // application. // // SKACERO.ActiveRow.ActiveCell cell = this.lvBalances[e.Row, e.Column]; // OPTION 2 // In the real world it's unlikely that we'll know the cell indices; // we're more likely to know the row key and the column-header key values which // means that we have to actually find the cell instead of going straight // to it. // string keyRow = currencies[e.Row]; // string keyColumn = currencies[e.Column-1]; // SKACERO.ActiveRow.ActiveCell cell = this.lvBalances.FindCell(keyRow, keyColumn); // OPTION 3 // If every cell is assigned a unique name then we can use it to locate // the cell within the grid. In this example, the unique key was simply generated // as a composite of the row name and column name but it could just as well have // been an integer or a guid. string keyCell = String.Format("{0}_{1}", currencies[e.Row], currencies[e.Column - 1]); SKACERO.ActiveRow.ActiveCell cell = this.lvBalances.FindCell(keyCell); if (cell != null) { // Create a new value for the cell. decimal newValue = Decimal.Add(cell.DecimalValue, e.Increment); // Has the value been reduced, increased, or left unchanged? if (newValue < cell.DecimalValue) { // Reduced cell.FlashBackColor = this.cbColourful.Checked ? Color.LightGreen : Color.Yellow; cell.FlashPreTextForeColor = Color.Red; cell.FlashPostTextForeColor = Color.Red; cell.FlashPreText = "▼"; cell.FlashPostText = String.Empty; } else if (newValue > cell.DecimalValue) { // Increased cell.FlashBackColor = this.cbColourful.Checked ? Color.PowderBlue : Color.Yellow; cell.FlashPreTextForeColor = Color.Blue; cell.FlashPostTextForeColor = Color.Blue; cell.FlashPreText = "▲"; cell.FlashPostText = String.Empty; } else { // Unchanged cell.FlashBackColor = Color.Yellow; cell.FlashPreText = String.Empty; cell.FlashPostText = String.Empty; } cell.DecimalValue = newValue; } } catch (IndexOutOfRangeException exc) { MessageBox.Show(exc.Message); } } }
}//UpdateActiveGridColumns() // // // // // // **** Create Summary Rows() **** // /// <summary> /// This creates a summary row, with a SortKey to group it just above /// those rows it describes. /// </summary> /// <param name="rowBaseName"></param> /// <param name="exchangeName"></param> /// <param name="prodName"></param> /// <param name="sortString"></param> private void CreateSummaryRows(string rowBaseName, string exchangeName, string prodName, string sortString = "") { SKACERO.ActiveRow aRow = new SKACERO.ActiveRow(); aRow.UseItemStyleForSubItems = false; if (string.IsNullOrEmpty(rowBaseName)) { aRow.Name = GroupRowNamePrefix; } else { aRow.Name = string.Format("{0}{1}", GroupRowNamePrefix, rowBaseName); } aRow.Text = aRow.Name; // // Load the remaining cells - empty. // for (int i = 1; i < this.activeGrid1.Columns.Count; i++) { SKACERO.ActiveRow.ActiveCell cell = new SKACERO.ActiveRow.ActiveCell(aRow, String.Empty); cell.Name = GetCellKey(aRow.Name, this.activeGrid1.Columns[i].Name); cell.DecimalValue = Decimal.Zero; cell.PreTextFont = new Font("Arial", cell.Font.Size, FontStyle.Bold); cell.PostTextFont = new Font("Arial", cell.Font.Size, FontStyle.Bold); Font font = cell.Font; cell.Font = new Font(font.Name, font.Size, FontStyle.Bold); cell.Format = "+0;-0; "; cell.Text = ""; aRow.SubItems.Add(cell); } // // SortKey must be constructed so this row appears just above the group it summarizes. // if (!string.IsNullOrEmpty(sortString)) { aRow.SubItems[GetCellKey(aRow.Name, "SortKey")].Text = string.Format("{0}", sortString); // user overriding sortString manually. } else if (string.IsNullOrEmpty(rowBaseName)) { aRow.SubItems[GetCellKey(aRow.Name, "SortKey")].Text = string.Format("0{0}", aRow.Name); } else { aRow.SubItems[GetCellKey(aRow.Name, "SortKey")].Text = string.Format("{0}0", rowBaseName); // usual sorting key. } // // Display content of row now. // if (!string.IsNullOrEmpty(exchangeName)) { aRow.SubItems[GetCellKey(aRow.Name, "Exchange")].Text = exchangeName; } if (!string.IsNullOrEmpty(prodName)) { aRow.SubItems[GetCellKey(aRow.Name, "Product")].Text = prodName; } // Add to our collection this.activeGrid1.SuspendLayout(); this.activeGrid1.Items.Add(aRow); activeGrid1.Sort(); this.activeGrid1.ResumeLayout(); // Clean up old instrument entries that are part of my subgroup. // This optional feature is that instrument rows will not display an // exchange nor product label when they have been grouped beneath a summary // row with this info. if (IsSuppressRepetativeExchangeProductLabels) { List <string> members; if (m_ExchangeGroups.TryGetValue(rowBaseName, out members)) { foreach (string instrName in members) { string keyCell = GetCellKey(instrName, "Exchange"); SKACERO.ActiveRow.ActiveCell aCell = this.activeGrid1.FindCell(keyCell); if (aCell != null) { //Log.NewEntry(LogLevel.Minor, "Viewer: Deleting cell {0} for {1}.", keyCell, instrName); aCell.Text = string.Empty; } } } if (m_ProductGroups.TryGetValue(rowBaseName, out members)) { foreach (string instrName in members) { string keyCell = GetCellKey(instrName, "Product"); SKACERO.ActiveRow.ActiveCell aCell = this.activeGrid1.FindCell(keyCell); if (aCell != null) { //Log.NewEntry(LogLevel.Minor, "Viewer: Deleting cell {0} for {1}.", keyCell, instrName); aCell.Text = string.Empty; } } } } }//CreateSummaryRows()
}//UpdateActiveGridCell() #endregion //ActiveGrid Update Methods #region ActiveGrid Creation Methods // ***************************************************************** // **** Active Grid Creation Methods **** // ***************************************************************** // // // private void ActiveGridAddNewRow(FillHub.PositionBookChangedEventArgs eventArgs) { InstrumentName instrumentName = eventArgs.Instrument; if (m_InstrumentInfos.ContainsKey(instrumentName.FullName) && activeGrid1.RowExists(instrumentName.FullName)) { // We already have a row for this instrument! Update its values. // Update things that depend on the the currency rate too... since this may have updated! [04 Jun 2013] InstrumentRowData info = m_InstrumentInfos[instrumentName.FullName]; IFillBook positionBook; if (m_FillHub.TryEnterReadBook(instrumentName, out positionBook)) { info.StartingRealPnL = Math.Round(positionBook.RealizedStartingDollarGains, 2); info.RealPnL = Math.Round(positionBook.RealizedDollarGains, 2); info.UnrealPnL = Math.Round(positionBook.UnrealizedDollarGains(), 2); m_FillHub.ExitReadBook(instrumentName); } SKACERO.ActiveRow row = activeGrid1.Items[instrumentName.FullName]; row.SubItems[GetCellKey(instrumentName.FullName, ColumnName_StartingRealPnL)].Text = info.StartingRealPnL.ToString("0.00"); row.SubItems[GetCellKey(instrumentName.FullName, ColumnName_RealPnL)].Text = info.RealPnL.ToString("0.00"); row.SubItems[GetCellKey(instrumentName.FullName, ColumnName_UnrealPnL)].Text = info.UnrealPnL.ToString("0.00"); row.SubItems[GetCellKey(instrumentName.FullName, "Expiry")].Text = m_InstrumentInfos[instrumentName.FullName].ExpirationDate.ToString("yyyy-MM-dd"); row.SubItems[GetCellKey(instrumentName.FullName, "Currency")].Text = info.CurrencyCode; row.SubItems[GetCellKey(instrumentName.FullName, "SortKey")].Text = string.Format("{0}{1}{2}{3}", instrumentName.Product.Exchange, instrumentName.Product.Type.ToString(), instrumentName.Product.ProductName, m_InstrumentInfos[instrumentName.FullName].ExpirationDate.ToString("yyyyMMdd")); activeGrid1.Sort(); // sort again, now we've changed the SortKey. return; } // // Create all tables we need for each new instrument. // m_InstrumentInfos.Add(instrumentName.FullName, new InstrumentRowData(instrumentName)); string strKey = instrumentName.Product.Exchange; if (!m_ExchangeGroups.ContainsKey(strKey)) // Exchange group { m_ExchangeGroups.Add(strKey, new List <string>()); // maintain an entry for each ex } if (!m_ExchangeGroups[strKey].Contains(instrumentName.FullName)) { m_ExchangeGroups[strKey].Add(instrumentName.FullName); if (m_ExchangeGroups[strKey].Count >= m_MinMembersForExchangeGroupRow && (!activeGrid1.Items.ContainsKey(string.Format("{0}{1}", GroupRowNamePrefix, strKey)))) { CreateSummaryRows(strKey, instrumentName.Product.Exchange, string.Empty); } } strKey = GetProductGroupKey(instrumentName); // Product group: construct the exch+prod group name. if (!m_ProductGroups.ContainsKey(strKey)) // first time this product group showed up! { m_ProductGroups.Add(strKey, new List <string>()); // create a place for this prod group to hold its membership list. } if (!m_ProductGroups[strKey].Contains(instrumentName.FullName)) // If this instrument is not yet part of group, add him. { m_ProductGroups[strKey].Add(instrumentName.FullName); // add new member of group if ((m_ProductGroups[strKey].Count >= m_MinMembersForProductGroupRow) && (!activeGrid1.Items.ContainsKey(string.Format("{0}{1}", GroupRowNamePrefix, strKey)))) { CreateSummaryRows(strKey, string.Empty, instrumentName.Product.ProductName); // need to add a new summary line } } // // Create the row. // SKACERO.ActiveRow aRow = new SKACERO.ActiveRow(); aRow.Name = instrumentName.FullName; aRow.Text = instrumentName.FullName; // this will appear in the zeroth column of the row. for (int i = 1; i < this.activeGrid1.Columns.Count; i++) { SKACERO.ActiveRow.ActiveCell cell = new SKACERO.ActiveRow.ActiveCell(aRow, String.Empty); cell.Name = GetCellKey(instrumentName.FullName, this.activeGrid1.Columns[i].Name); cell.DecimalValue = Decimal.Zero; cell.PreTextFont = new Font("Arial", cell.Font.Size); cell.PostTextFont = new Font("Arial", cell.Font.Size); aRow.SubItems.Add(cell); } // Load constant cells aRow.SubItems[GetCellKey(instrumentName.FullName, "Expiry")].Text = m_InstrumentInfos[instrumentName.FullName].ExpirationDate.ToString("yyyy-MM-dd"); aRow.SubItems[GetCellKey(instrumentName.FullName, "SortKey")].Text = string.Format("{0}{1}{2}{3}", instrumentName.Product.Exchange, instrumentName.Product.Type.ToString(), instrumentName.Product.ProductName, m_InstrumentInfos[instrumentName.FullName].ExpirationDate.ToString("yyyyMMdd")); aRow.SubItems[GetCellKey(instrumentName.FullName, ColumnName_Alias)].Text = instrumentName.SeriesName; // Load Exchange cell optionally strKey = instrumentName.Product.Exchange; if (IsSuppressRepetativeExchangeProductLabels && activeGrid1.Items.ContainsKey(string.Format("{0}{1}", GroupRowNamePrefix, strKey))) { aRow.SubItems[GetCellKey(instrumentName.FullName, "Exchange")].Text = string.Empty; } else { aRow.SubItems[GetCellKey(instrumentName.FullName, "Exchange")].Text = instrumentName.Product.Exchange; } // Load Product cell, optionally. strKey = GetProductGroupKey(instrumentName); if (IsSuppressRepetativeExchangeProductLabels && activeGrid1.Items.ContainsKey(string.Format("{0}{1}", GroupRowNamePrefix, strKey))) { aRow.SubItems[GetCellKey(instrumentName.FullName, "Product")].Text = string.Empty; } else { aRow.SubItems[GetCellKey(instrumentName.FullName, "Product")].Text = instrumentName.Product.ProductName; } // Set currency column as empty string. aRow.SubItems[GetCellKey(instrumentName.FullName, "Currency")].Text = string.Empty; // Add row to our collection this.activeGrid1.SuspendLayout(); try { if (!this.activeGrid1.Items.ContainsKey(aRow.Name)) { this.activeGrid1.Items.Add(aRow); } } catch (Exception e) { if (Log != null) { Log.NewEntry(LogLevel.Major, "ActiveGridAddNewRow: Failed to add new row with name {0}. Execption {1}", aRow.Name, e.Message); } } activeGrid1.Sort(); this.activeGrid1.ResumeLayout(); // Update the row ActiveGridUpdatePosition(eventArgs); }//ActiveGridAddNewRow()