overriding displayOption to color certain lines according to a value from displayMethod - axapta

I am trying to override the displayOption on my form so that I color certain lines following certain conditions, When my condition was related to a normal field I had no problem with that, example code:
public void displayOption(Common _record, FormRowDisplayOption _options)
{
if (_record.(fieldnum(MY_Table,My_Field))=="YES")
{
_options.backColor(WinAPI::RGB2int(161,161,255));
}
super(_record, _options);
}
but my problem is, I want to make a condition on a displayMethod not a normal field

A display method will work, you just need to cast the Common _record to your table buffer, then you can access the table method.
So if it was SalesTable, you would create:
SalesTable salesTable;
salesTable = _record as SalesTable;
if (salesTable.yourTableDisplayMethod == "whatever") { // Do something }
Then you can use the display method as normal.

Related

Disable Conditional Formatting for specific column

Starting from WinForms Data Grid v14.2 by enabling the GridOptionsMenu.ShowConditionalFormattingItem property, the Conditional Formatting feature becomes available.
By doing a right click on any column header, the Conditional Formatting menu item is showed up, allowing end-users to apply conditional formatting to grid columns.
My question is that is it possible to disable the feature for a specific column? I'm thinking of having the menu item grayed out, or simply not having it (by hiding it somehow) in the list of items.
I'm aware of the fact that the cells of a specific column can be formatted by the conditional formattings put on other columns by applying the formatting to the entire row. But, my goal is only to make sure the user can not access the functionality for a specific column.
You can remove the corresponding menu-item using the GridView.PopupMenuShowing event:
using System.Windows.Forms;
using DevExpress.XtraGrid.Localization;
using DevExpress.XtraGrid.Menu;
using DevExpress.XtraGrid.Views.Grid;
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
gridView1.PopupMenuShowing += gridView1_PopupMenuShowing;
}
void gridView1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e) {
var columnMenu = e.Menu as GridViewColumnMenu;
if(columnMenu != null && columnMenu.Column == this.gridColumn1) {
var conditionalFormattingItem = e.Menu.Items.FirstOrDefault(x => object.Equals(x.Tag, GridStringId.MenuColumnConditionalFormatting));
if(conditionalFormattingItem != null)
conditionalFormattingItem.Visible = false;
}
}
}
}

How to simple overwrite showContextMenu on all columns of a grid?

If I overwrite showContextMenu on a grid it only add additional menu to the pop up menu when I click on a grid but do not click on any column. One way is to overwrite showContextMenu on all columns in grid but this solution does not looks right. Is there some better way how to insertItem to showContextMenu on all columns of a grid?
I am using AX 2012.
Standard code works only if grid is clicked but not a single column of a grid.
int ret,ii;
int myMenu = 2;
PopupMenu popupMenu = PopupMenu::create(_menuHandle);
FormListItem item;
;
deleteAttachment = popupMenu.insertItem('My menu');
ret = super(_menuHandle);
if(ret == myMenu)
{
//My code
}
return ret;
You need to use method registerOverrideMethod.
You can test how it works as follows. E.g. you have a form with a grid (property Name = 'Grid', AutoDeclaration = 'Yes'), and there are a few StringEdit controls in that grid.
1) Create following method in your form:
public void formControlContext(FormStringControl _formStringControl)
{
_formStringControl.context();
info(strFmt(#"Overridden context of control '%1'", _formStringControl.name()));
}
2) Override method init in your form:
public void init()
{
FormStringControl fsc;
int controlNum;
super();
for (controlNum = 1; controlNum <= Grid.controlCount(); controlNum++)
{
fsc = Grid.controlNum(controlNum);
fsc.registerOverrideMethod(methodStr(FormStringControl, context), identifierStr(formControlContext));
}
}
You only need to modify method 'formControlContext' according to your needs.
P.S. I just noticed you need to override method showContextMenu anot not context. The idea is the same - use registerOverrideMethod. You can override any method this way.
I've never played with overwriting the ShowContextMenu, but I did just make a blog post about how to recursively loop over every form control that sounds like it might help you.
http://alexondax.blogspot.com/2014/05/how-to-use-recursion-to-loop-over-form.html
I'd imagine you could create some sort of handler and key/value thing if you're creative.

DevExpress XtraGrid FocusedRowChanged event problem when changing datasource

This problem has bugged me for several years and maybe someone here knows a simple solution, since I just ran into it again.
QUESTION: Is there any way to get the XtraGrid to "forget" the current focused row index before a new (different) datasource is assigned to the grid?
BACKGROUND
We use the XtraGrid as a kind of controller for what is displayed in another panel of a multipane Winform.
Now imagine a hypothetical scenario where the datasource of the XtraGrid keeps changing according to menu selections. Menu item 1 populates the grid with a list of today's entrees in the cafeteria: Id, Name. Menu item 2 populates the grid with a list of Customers the user must phone that day: ID, Name. Important thing is that these are separate distinct datasources, and the grid's datasource is being assigned and reassigned.
CRITICAL FACT FOR THIS QUESTION:
We want the grid's FocusedRowChanged event to be the single place where we trap the user's selection in the controller grid. We are a "no spaghetti code" shop. FocusedRowChanged is better than a click event because it handles keyboard navigation too. The row with the focus contains the ID of the detail record we need to fetch from the database for display in Panel #2. This works--most of the time.
Here's how it doesn't work: let's say that on a given day, the list of customers the user must contact contains only one row. So the first (and only) row in the grid is the focused row. Now let's say that the user goes up to the menu and selects the menu item to display the day's cafeteria entrees. When the user clicks on the first item in the Entrees list, the FocusedRowChanged event does NOT fire because the grid has retained a memory of the focused row index from the previous datasource. The focused row index has not changed. And thus the user's selection doesn't trigger anything.
I tried to get DevExpress to offer a second more row-object-oriented mode (as distinct from row-index-oriented approach) whereby each row in the grid would have a GUID, and the FocusedRowChanged event would fire whenever the GUID of the currently focused row differed from the GUID of the previously focused row, regardless of whether the focused row index happened to be the same. This would allow dynamic changes of datasource and enable the desired behavior. But they demurred.
So I'll ask my question again, Is there any way to get the XtraGrid to "forget" the current focused row index before a new datasource is assigned to the grid?
Tim, I had the exact same problem when the grid only had one row of data in it and then changed data sources. I solved it by setting the gridview.FocusedRowHandle = -1 after setting the new datasource.
In a similar situation, I am subscribing to the
FocusedRowObjectChanged
event (using DevExpress 16.1).
I think that the best solution to this problem is to create a new GridView object and override its DoChangeFocusedRowInternal method. Below you will find the default implementation of this method. All you need to do is to change the marked row just as your needs dictate. Also, take a look at the How to create a GridView descendant class and register it for design-time use article, it contains some useful information.
public class MyGridView : GridView {
protected override void DoChangeFocusedRowInternal(int newRowHandle, bool updateCurrentRow) {
if(this.lockFocusedRowChange != 0) return;
if(!IsValidRowHandle(newRowHandle))
newRowHandle = DevExpress.Data.DataController.InvalidRow;
if(FocusedRowHandle == newRowHandle) return; // <<<<<<
int currentRowHandle = FocusedRowHandle;
BeginLockFocusedRowChange();
try {
DoChangeFocusedRow(FocusedRowHandle, newRowHandle, updateCurrentRow);
}
finally {
EndLockFocusedRowChange();
}
RaiseFocusedRowChanged(currentRowHandle, newRowHandle);
}
}
UPDATE
My code:
namespace MyXtraGrid {
public class MyGridControl : GridControl {
protected override BaseView CreateDefaultView() {
return CreateView("MyGridView");
}
protected override void RegisterAvailableViewsCore(InfoCollection collection) {
base.RegisterAvailableViewsCore(collection);
collection.Add(new MyGridViewInfoRegistrator());
}
}
public class MyGridViewInfoRegistrator : GridInfoRegistrator {
public override string ViewName { get { return "MyGridView"; } }
public override BaseView CreateView(GridControl grid) {
return new MyGridView(grid as GridControl);
}
}
public class MyGridView : GridView {
public MyGridView(GridControl ownerGrid) : base(ownerGrid) { }
public MyGridView() { }
protected virtual bool RowEqual(int focusedRowHandle, int newRowHandle) {
if(IsDesignMode)
return focusedRowHandle == newRowHandle;
DataRow row1 = GetDataRow(focusedRowHandle);
DataRow row2 = GetDataRow(newRowHandle);
return row1 == row2;
}
protected override void DoChangeFocusedRowInternal(int newRowHandle, bool updateCurrentRow) {
if(this.lockFocusedRowChange != 0) return;
if(!IsValidRowHandle(newRowHandle))
newRowHandle = DevExpress.Data.DataController.InvalidRow;
if(RowEqual(FocusedRowHandle, newRowHandle))
return;
int currentRowHandle = FocusedRowHandle;
BeginLockFocusedRowChange();
try {
DoChangeFocusedRow(FocusedRowHandle, newRowHandle, updateCurrentRow);
}
finally {
EndLockFocusedRowChange();
}
RaiseFocusedRowChanged(currentRowHandle, newRowHandle);
}
}
}
You can subscribe on the DataSourceChanged event which will fire when Data source changes (you guessed it!) so then you can get using GetFocusedObject() the object and display the relevant items for the other grid...

Flex Advanced Datagrid Condition Row Background Color

I am trying to set the row background color for the advanced data grid control in Flex 3. Does anyone know if this is possible using a style function. Currently my style function looks like:
public function myStyleFunc(data:Object, col:AdvancedDataGridColumn):Object
{
if (data["status"] == "PRICING")
return {color:0xFF0000 , fontWeight:"bold" , backgroundColor:0xFF0000};
// Return null if the Artist name does not match.
return null;
}
However the background color does not change.
I have heard on the grape vine that I may need to override some methods to enable the background color property.
Any help would be appreciated .
Regards Karl
I have done some thing like that but in my case color was also coming from data also but it will help you.
You have to override the Datagrid and override drawRowBackground method
public class CustomDataGrid extends AdvancedDataGrid
{
protected override function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void{
var XMLdata:XML=rowNumberToData(dataIndex) as XML;
if(XMLdata!=null){
if(XMLdata.attribute(Constants.col) != undefined && XMLdata.attribute(Constants.col) != ""){
color=XMLdata.attribute(Constants.col);
}else{
color=0xFFFFFF;
}
}
super.drawRowBackground(s,rowIndex,y,height,color,dataIndex);
}
}
By this you can get any data from the row and according to it give the color.

How do you add a row listener to a Flextable in GWT?

How do you add a row listener to a specific row, or all rows in a table? I need to add a type of "onMouseOver" listener to the rows so that when you hover over them, it changes the background color of the row, much like getRowFormatter will allow you to do.
// this is click
final FlexTable myTable = new FlexTable();
myTable.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Cell cell = myTable.getCellForEvent(event);
int receiverRowIndex = cell.getRowIndex(); // <- here!
}
});
Supposing GWT 1.5.3:
CLICK EVENT HANDLING
If you are using FlexTable and you wanted a click event handler, you could use the FlexTable.addTableListener() and register your own TableListener. The TableListener object will need to implement the onCellClicked callback which would give you the row number.
OTHER EVENTS HANDLING (e.g. HOVER)
If you need to handle other type of events other than click (say, hover), GWT currently doesn't have a ready interface for that. You pretty much left on your own to implement them yourself. There's two ways of doing it that I can think of now:
The quick and dirty way, is probably by exploiting JSNI, which provides a means for you to inject Javascript into your GWT code. I didn't use much JSNI (apart from really hard workarounds which is not worth the effort writing it in pure GWT) in my code so I can't show you an example; but frankly I won't recommend this as it reduces maintainability and extensibility.
If you wanted a native, GWT interface, you can create a new class that inherits HTMLTable or FlexTable. At the constructor, call the sinkEvents function with your needed events. (e.g. for hover, you'll probably need sinkEvents(Event.ONMOUSEOVER)). Then you'll need the onBrowserEvent function that handles the mouseover.
A quick template of how the code should look like:
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
public class FlexTableWithHoverHandler
extends FlexTable
{
public FlexTableWithHoverHandler()
{
super();
sinkEvents(Event.ONMOUSEOVER);
}
#Override
public void onBrowserEvent(Event event)
{
switch(DOM.eventGetType(event))
{
case Event.ONMOUSEOVER:
// Mouse over handling code here
break;
default:
break;
}
}
}
The best of learning how to code this is by looking at the GWT source code itself (search for sinkEvent) and getting the feel on how to do it the GWT way.
I found it much simple to add javascript directly to the TR element. My code assumes that a widgets DOM parent is a TD and the grandparent is the TR so you need to be sure you know your DOM.
Here's my code. Nice and simple, no JSNI or GWT DOM event management required.
TableRowElement rowElement = (TableRowElement) checkbox.getElement().getParentElement().getParentElement();
rowElement.setAttribute("onMouseOver", "this.className='" + importRecordsResources.css().normalActive() + "'");
rowElement.setAttribute("onMouseOut", "this.className='" + importRecordsResources.css().normal() + "'");
I just did it this simple way:
protected void handleRowsSelectionStyles(ClickEvent event) {
int selectedRowIndex = fieldTable.getCellForEvent(event).getRowIndex();
int rowCount = fieldTable.getRowCount();
for (int row = 0; row < rowCount; row++) {
Element rowElem = fieldTable.getRowFormatter().getElement(row);
rowElem.setClassName(row == selectedRowIndex ? "row selected" : "row");
}
}
You call this method from the cells you want to be clickable
int row = 0;
for (final RowDataProxy rowData : rowDataList) {
Label fieldName = new Label(rowData.name());
fieldName.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
handleRowsSelectionStyles(event);
}
});
fieldTable.setWidget(row++, 0, fieldName);
}
Best Regards,
Zied Hamdi

Resources