I'm sorry for mistake I'm french.
So I have a tableView empty. I have a button "Add" when on click added row in a tableView. And when I select an row in my tableView, a new button "Cancel" show.
And when I click on a button "Cancel", the row's css change on my row selected (added a class css ".cancel").
The problem is that I click on button "Cancel", and after I click in the button "Add", the css ".cancel" is applicated at an other row while I don't clicked in the button "Add".
I think that there is a problem in index row.
In my method initialize :
articleTable.setRowFactory(param -> new TableRow<LigneTicket>() {
#Override
protected void updateItem(LigneTicket paramT, boolean empty) {
super.updateItem(paramT, empty);
if (!isEmpty() && paramT != null && paramT.getArticle().isArticleCanceled()) {
getStyleClass().add("cancel");
}
}
});
my code on button "Cancel" :
public void cancelLigneTicket() {
int indexSelected = articleTable.getSelectionModel().getSelectedIndex();
articleTable.getItems().get(indexSelected).getArticle().setArticleAnnuler(true);
articleTable.getSelectionModel().clearSelection();
List<LigneTicket> items = new ArrayList<>(articleTable.getItems());
articleTable.getItems().setAll(items);
buttonAnnulArt.setVisible(false);
Help !!
Thanks.
TableRows are used to display the table items. That doesn't mean however, that it will be used with only one item.
This can result in the following sequence of events for a row r:
The item of r is updated to a canceled item and thus the cancel CSS class is added.
The item of r is updated to a non-canceled item, but the cancel CSS class is not removed.
You need to remove the class again. Furthermore with your code the style class could be added multiple times leading to unnecessary memory consumption.
boolean canceled = !empty && paramT != null && paramT.getArticle().isArticleCanceled());
if (canceled) {
if (!getStyleClass().contains("cancel"))
getStyleClass().add("cancel");
} else {
getStyleClass().remove("cancel");
}
or using PseudoClass:
private static final PseudoClass CANCELED = PseudoClass.getPseudoClass("cancel");
...
pseudoClassStateChanged(CANCELED, !empty && paramT != null && paramT.getArticle().isArticleCanceled());
Furthermore you should prefer the TableView.refresh (available in JavaFX >= 8u60) method to refresh the cell items instead of copying the list and setting the items.
Related
My first question here so I hope i can describe my problem correct.
What im facing right now is that i want to display a contextmenu for some entries of a JFXTreeTableView. Therefore i created a new cellFactory called "ProjectTreeItemWithContextMenuTreeTableFactory" which handles the creation of the contextMenu based on mouseReleasedEvent and displaying it.
Due to i dont have 10 reputations i cant post images but as an example what isnt working i try to describe it. If i open the contextmenu it will get displayed at the correct position. When hovering over a menu entry the menuItems will get displayed, but not rendered right next to the menu.
There can be some times a huge gab between the menuItems and the menu whic hwas hovered....
What i noticed is, that this problem will only occur when hovering for the first time over the menu. If hovering for the second time over the menu while the contextMenu stays open, everything will get displayed correct.
private class TreeTableCallback extends TreeTableCell<T, ProjectTreeParentItemFX> {
#Override
protected void updateItem(ProjectTreeParentItemFX item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
setContextMenu(null);
} else {
this.setOnMouseReleased(evt -> handleMouseReleased(evt, item));
setText(item.getDisplayText());
}
}
Adding menus and menuItems to the contextMenu and showing the menu.
private void handleMouseReleased(MouseEvent evt, ProjectTreeParentItemFX item) {
if (evt.getButton().equals(MouseButton.SECONDARY)) {
setContentOfContextMenuBasedOnType(item);
contextMenu.show(getTreeTableRow(), evt.getScreenX(), evt.getScreenY());
}
}
I want to multi select row in my TableView. The problem is that my application is a multitouch application, I have not a keyboard, so not a CTRL key.
I have a code follow :
tableViewArticle.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
But I want to select a lot of row only with a mouse click. For exemple, when I selected one row, the row change in blue, and if after I select an other row, I have two rows in blue.
You could use a custom event filter for the TableView that handles the selection, if a click happened on a table row:
tableViewArticle.addEventFilter(MouseEvent.MOUSE_PRESSED, evt -> {
Node node = evt.getPickResult().getIntersectedNode();
// go up from the target node until a row is found or it's clear the
// target node wasn't a node.
while (node != null && node != tableViewArticle && !(node instanceof TableRow)) {
node = node.getParent();
}
// if is part of a row or the row,
// handle event instead of using standard handling
if (node instanceof TableRow) {
// prevent further handling
evt.consume();
TableRow row = (TableRow) node;
TableView tv = row.getTableView();
// focus the tableview
tv.requestFocus();
if (!row.isEmpty()) {
// handle selection for non-empty nodes
int index = row.getIndex();
if (row.isSelected()) {
tv.getSelectionModel().clearSelection(index);
} else {
tv.getSelectionModel().select(index);
}
}
}
});
If you want to handle touch events differently to mouse events, you can also use MouseEvent.isSynthesized to check, if the event is a touch event.
I have buttons in xtragrid cell . i want to get row index when i clicked to repository button item. How can i get cell info or index..
I wanna show cell info at anotherp page which respository button clicked in row cell..
Can you help me ?
Thanks for advice..
To get the information about Grid HitInfo check the Hit Information Overview and Samples of Using Hit Information documentation:
private void gridView1_MouseDown(object sender, MouseEventArgs e) {
// obtaining hit info
GridHitInfo hitInfo = gridView1.CalcHitInfo(new Point(e.X, e.Y));
if (((e.Button & MouseButtons.Right) != 0) && (hitInfo.InRow) &&
(!gridView1.IsGroupRow(hitInfo.RowHandle))) {
// switching focus
gridView1.FocusedRowHandle = hitInfo.RowHandle;
// showing the custom context menu
ViewMenu menu = new ViewMenu(gridView1);
DXMenuItem menuItem = new DXMenuItem("DeleteRow",
new EventHandler(DeleteFocusedRow));
menuItem.Tag = gridView1;
menu.Items.Add(menuItem);
menu.Show(hitInfo.HitPoint);
}
}
Check this:
private void repositoryItemButtonEdit_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
{
myGridView.DeleteRow(myGridView.FocusedRowHandle); /// you can get focusedRowHandle here
}
Reference:
Winforms XtraGrid Delete Row Button
Delete button on each row of grid - how do we prevent the user from typing text in the new column with the delete button
Edit:
Refere this Devexpres thread: Cannot get the rowhandle to delete a row using RepositoryItemButtonEdit
I have a . I provide arraylist as its data provider. my question is why moves to the ing location in when I select any item using enter key. Also when I press space from keyboard, again moves to ing location. How can I fix this? Thanks
protected function onInputKeyDown(e:KeyboardEvent):void
{
if(e.keyCode == 13)
{
AddPath(cb.textInput.text);
cb.dataProvider = recentList;
}
}
here recentList is a Bindable ArrayList. Every Time when I enter anything in ComboBox and press Enter, The cursor moves to the beginning in the Text Area of ComboBox. AddPath function simply adds the new data to the recentList.
When you set cb.dataProvider = recentList; you are essentially assigning a new pointer which overrides the previous list and resets the cursor.
You should be able to create a variable containing the selected item and manually set the ComboBox to that item on click/enter after you carry out the cb.dataProvider = recentList;
protected function onInputKeyDown(e:KeyboardEvent):void
{
if(e.keyCode == 13)
{
var selectedItem:String = cb.selectedItem
AddPath(cb.textInput.text);
cb.dataProvider = recentList;
cb.selectedItem(selectedItem);
}
}
Apologies if the code isn't perfect, but the theory should be right.
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...