| | | | Browse by category |
Problem
Is there a way to specify the format for cells?
Cause
Action
Objective Grid 6.0 introduces the new CGXStyle::SetFormat() for number formatting. Check out the class reference on this attribute. When using CGXStyle::SetFormat() make sure the value type for the cells that you want to format is GX_VT_NUMERIC. See CGXStyle::SetValueType().
Here is an example how to use this new attribute:
SetExpressionRowCol(nRow, 1, _T("General")); SetExpressionRowCol(nRow+1, 1, _T("7777.77")); SetStyleRange(CGXRange(nRow+1, 1), CGXStyle().SetFormat(GX_FMT_GEN).SetPlaces(15)); SetExpressionRowCol(nRow, 2, _T("Fixed")); SetExpressionRowCol(nRow+1, 2, _T("7777.77")); SetStyleRange(CGXRange(nRow+1, 2), CGXStyle().SetFormat(GX_FMT_FIXED).SetPlaces(4)); SetExpressionRowCol(nRow, 3, _T("Scientific")); SetExpressionRowCol(nRow+1, 3, _T("7777.77")); SetStyleRange(CGXRange(nRow+1, 3), CGXStyle().SetFormat(GX_FMT_FLOAT).SetPlaces(4)); |
Sometimes, you may be interested in formatting cells on your own without using the CGXStyle::SetFormat() attribute. You then have the option to a) override GetStyleRowCol() and StoreStyleRowCol() or b) to subclass a control from CGXEditControl.
You could override the GetStyleRowCol() method and change the value in your overridden method:
BOOL CMyGrid::GetStyleRowCol(ROWCOL nRow, ROWCOL nCol, CGXStyle& style,...) { |
|||
if (!CGXGridCore::GetStyleRowCol(nRow, nCol, style, ...) | |||
return FALSE; | |||
if (nCol == yourSpecifcCol) { |
|||
// get value with style.GetValueRef() char s[20]; wsprint(s, "$%g", value); style.SetValue(s); |
|||
}
return TRUE; |
|||
}
BOOL CMyGrid::StoreStyleRowCol(ROWCOL nRow, ROWCOL nCol, const CGXStyle* pStyle,...) |
|||
if (nCol == yourSpecifcCol && pStyle->GetIncludeValue()) { |
|||
CGXStyle style = *pStyle; CString s = style.GetValueRef(); // remove $ from value return CGXGridCore::StoreStyleRowCOl(nRow, nCol, &style,..); |
|||
}
return CGXGridCore::StoreStyleRowCOl(nRow, nCOl, pStyle, ...); |
|||
} |
You can derive a class from CGXEditControl and format the value as it should be displayed in the cell. The format can be stored in a user attribute.
If you implement the following class CNumericEditControl:
// header (.h) file
class CNumericEditControl: public CGXEditControl |
||||
DECLARE_CONTROL(CNumericEditControl) | ||||
public: | ||||
// Constructor & Destructor CNumericEditControl(CGXGridCore* pGrid, UINT nID); |
||||
protected: | ||||
// Overrides BOOL GetControlText(CString& strResult, ROWCOL nRow, ROWCOL nCol, LPCTSTR pszRawValue, const CGXStyle& style); BOOL ValidateString(const CString& sEdit); // Generated message map functions DECLARE_MESSAGE_MAP() |
||||
};
// implementation (.cpp) file // CNumericEditControl control IMPLEMENT_CONTROL(CNumericEditControl, CGXEditControl) CNumericEditControl::CNumericEditControl(CGXGridCore* pGrid, UINT nID) |
||||
: CGXEditControl(pGrid, nID) | ||||
{
} BEGIN_MESSAGE_MAP(CNumericEditControl, CGXEditControl) |
||||
//{{AFX_MSG_MAP(CNumericEditControl) //}}AFX_MSG_MAP |
||||
END_MESSAGE_MAP()
// GetControlText |
||||
// base class version will store current text in sResult if (!CGXEditControl::GetControlText(sResult, nRow, nCol, pszRawValue, style)) |
||||
return FALSE; | ||||
if (!sResult.IsEmpty()) { |
||||
// gather information
// ... value // ... format // Now, format the text |
||||
}
return TRUE; |
||||
}
BOOL CNumericEditControl::ValidateString(const CString& sEdit) |
||||
// cycle through string and check each character if it is a digit for (int n = 0; n < sEdit.GetLength(); n++) { |
||||
if (!isdigit(sEdit[n]) && sEdit[n] != '.') | ||||
return FALSE; | ||||
}
return TRUE; |
||||
} |
You can register the control and user attribute in the OnInitialUpdate() routine of your grid class
// Register all controls and user attributes for the view // IDS_CTRL_NUMEDIT and IDS_UA_NUMEDITFORMAT are string resource // ids you have to add to your application. RegisterControl(IDS_CTRL_NUMEDIT, new CNumericEditControl(this, IDS_CTRL_NUMEDIT)); GetParam()->GetStylesMap()->AddUserAttribute(IDS_UA_NUMEDITFORMAT); |
and later apply it to cells with
SetStyleRange(CGXRange(4,3,10,5), | |||
CGXStyle() | |||
.SetControl(IDS_CTRL_NUMEDIT) .SetUserAttribute(IDS_UA_NUMEDITFORMAT, "%.3f") .SetHorizontalAlignment(DT_RIGHT) |
|||
); |
The user can also change the numeric formatting of cells with the Format|Cells dialog if he clicks on the "User" property sheet.
See also the date control in the dbfbrows sample. It implements a date control for international dates.
If you want the full number to be displayed when the cell is in edit mode, you should also override SetValue(). For example if the cell is formatted to show 2 decimal place. When user input 1.23456 and hit enter, the cell should show 1.23. When the user edit that cell (by F2 or click on the text in the cell), 1.23456 (the full number) should be displayed.
void CNumericEditControl::SetValue(LPCTSTR pszRawValue) { |
|||
// Convert the value to the text which should be // displayed in the current cell and show this // text. if (m_hWnd) |
|||
SetWindowText(pszRawValue); | |||
} |