I'm noob in GTK#, just making my first steps here..
Working now with TreeView GTK. Have already read this tutorial: https://www.mono-project.com/docs/gui/gtksharp/widgets/treeview-tutorial/
and make everything I need (adding data from my own class, column sorting with sorting functions)
But, according to the Title - I have 2 questions:
I need to refresh tree view with new data. And I don't want to "loose" scroll and selection. So the easiest way to clear liststore and fill with new data not works for me (I loose scroll). I need to update rows. I've already learned how to get values from TreeView.Model (iter as my class) - Question is how can I update Iters.
Is there any way to disable 3-d column sort position "default". When I click on column I can see Acc, Desc, modes and then some 3-d position (without sorting arrows). Now I make it in that way(remember sorting mode and column, and after refresh I selecting saved mode and column):
void Sortable_SortColumnChanged(object sender, EventArgs e)
{
int a;
SortType b;
sortable.GetSortColumnId(out a, out b);
if (a == -1)
{
if (default_sort_type == SortType.Ascending) default_sort_type = SortType.Descending;
else default_sort_type = SortType.Ascending;
sortable.SetSortColumnId(default_column, default_sort_type);
}
else
{
default_column = a;
default_sort_type = b;
}
}
But I think there is better way...
Related
HandsonTable is not rendering all rows - it loads only part of all rows. But when I do Ctrl+A and paste into Excel I see all the rows. Why is Handsontable not displaying all the rows?
<hot-table col-headers="true" row-headers="true" datarows="data" context-menu width="1080">
<hot-column ng-repeat="column in columns" data="{{column.data}}"></hot-column>
</hot-table>
To render all rows, just set renderAllRows: true
The current answer does not answer the original question.
Handsontable does not render all cells at once because it is designed to be efficient for very large data sets. It does this using virtual rendering, dynamically modifying the DOM to include only the cells at the scroll position.
The rows virtual rendering can be disabled by setting renderAllRows: true, as described in the docs: "If typed true then virtual rendering mechanism for handsontable will be disabled." Although it will then not be as efficient for large data sets.
You can also change the number of pre-rendered rows and columns instead of rendering them all. From the performance tips,
You can explicitly specify the number of rows and columns to be rendered outside of the visible part of the table. In some cases you can achieve better results by setting a lower number (as less elements get rendered), but sometimes setting a larger number may also work well (as less operations are being made on each scroll event). Tweaking these settings and finding the sweet spot may improve the feeling of your Handsontable implementation.
This is done by setting viewportRowRenderingOffset and viewportColumnRenderingOffset in the handsontable options. These are by default set to auto which lets handsontable try to find the best value, but may be provided an integer value (e.g. viewportRowRenderingOffset: 70, viewportColumnRenderingOffset: 70).
I had the same problem (using HandsOnTable 6.2.1 and the old AngularJS) and customers would start complaining about not being sure if they were at the end of the table or not.
I was able to create two buttons linked to the functions 'scrollToBeginning' and 'scrollToEnd'. This way the user is sure to be at the last line. Three things specific about my answer:
I expose the functions to the DOM using $scope;
I have an object 'goToLine' holding 3 properties (scrollingToEnd: boolean, row: number, col: number), it is used in other functions not posted here;
I have a list of ID referencing HandsOnTable objects stored in $scope.hots.
Here is my raw solution, feel free to adapt / enhance:
$scope.stopScrollingToEnd = function () {
$scope.goToLine.scrollingToEnd = false;
};
$scope.scrollToBeginning = function (goToLine) {
$scope.stopScrollingToEnd();
const hot = $scope.hots[goToLine.id];
hot.scrollViewportTo(0, 0);
};
/**
* Scroll to the end of the List Element.
* We need this functionality because of a bug in HandsOnTable related to its Virtualization process.
* In some cases (complex table), when manually scrolling, the max row is wrong, hence causing major confusion for the user.
* #param {*} goToLine
* #returns
*/
$scope.scrollToEnd = function (goToLine) {
// We scroll to the first line before going to the last to avoid the bug and being sure we get to the last line
$scope.scrollToBeginning(goToLine);
const hot = $scope.hots[goToLine.id];
var numberOfRows = hot.countRows();
// This variable is used to repeat the scrollViewportTo command.
// It is built using the length of `numberOfRows`.
var repeat = numberOfRows ? 1 * Math.ceil(Math.log10(numberOfRows + 1)) : 1;
// Used in other goTo function to avoid conflict.
$scope.goToLine.scrollingToEnd = true;
// FIXME : not supposed to call scrollViewportTo several times... => fixed in recent versions of HandsOnTable ?
for (let n = 0; n < repeat; n++) {
if (!$scope.goToLine.scrollingToEnd) {
return;
}
setTimeout(function () {
if (!$scope.goToLine.scrollingToEnd) {
return;
}
hot.scrollViewportTo(numberOfRows - 1, 0);
}, 500);
}
};
Is there any way i can hide HOT columns from javascript?
The requirement is such that the column to hide will come as a parameter in javascript and based on that the respective column will show hide accordingly.
The HOT has rowHeaders and colHeaders and the data with 20 columns.
Please advise.
OUTDATED SOLUTION
Ok I founnd a possible solution. I tested it out on my own system but it's actually quite simple.
You should be using a customRenderer in your columns option. Read up about this if you aren't already. The idea is that you're giving each cell its own renderer. In this custom function, you can do something like this:
var colsToHide = [3,4,6]; // hide the fourth, fifth, and seventh columns
function getCustomRenderer() {
return function(instance, td, row, col, prop, value, cellProperties) {
if (colsToHide.indexOf(col) > -1) {
td.hidden = true;
} else {
td.hidden = false;
}
}
}
What this renderer does is hide the cells that the var colsToHide specify. All you do now is add a DOM element that lets the user pick which and so every time the table gets rendered (which happens basically after any change, or manually triggered need be), the cells in the columns specified will be hidden, keeping the data array intact like you described. And when not in colsToHide they are re-rendered so make sure you get that working as well.
Here I implemented it with very basic functionality. Just enter the index of a column into the input fields and watch the magic happen.
http://jsfiddle.net/zekedroid/LkLkd405/2/
Better Solution: handsontable: hide some columns without changing data array/object
Ok, let me explain my scenario more clearly:
When a cell is edited, it becomes 'dirty' and I style it a certain way by adding a CSS class to the cell via javascript.
Then, if the user Sorts the grid, the styling is lost (I believe because all the rows are recreated) and I need a way to restore the styling to the appropriate cell/row after a Sort.
What I attempted to do is add an entry into data[] called 'status' and onCellChange I loop through data[] and match the args.item.Id to appropriate entry in data[].
grid.onCellChange.subscribe(function (e, args) {
var done = false;
for (var i = 0; i < data.length && !done; i++) {
if (data[i].id == args.item.id) {
data[i].status = "dirty";
done = true;
}
}
}
However, onSort I'm not sure how to match the sorted rows to the data array. (Since I have no args.item) I've attempted to do selector statements:
$(".slick-row")
to restyle the correct cells, but I have no way to associate the rows with their entry in data[].
1) There is no need to search for the item in your onCellChange handler - it is available at "args.item".
2) Sorting the "data" array will not wipe out your change to the item in #1.
3) You mention dynamically styling cells. I see no code for that. If your custom formatter is the piece of code that looks at "item.status" and renders it differently if it is dirty, then you don't have to do anything extra. Sorting the data and telling the grid to re-render will preserve the "dirty" cell styles.
ok, here is the story...
I have 3 textfield for user to select....
[textfield A][textfield B][textfield C]
and a confirm button, the user need to add three textfield, after that , the user need to click the confirm button.... but based on different select order, the result is different, for example:
A>B>C, I will show red.
When the user select in this order:
B>A>C I will show green.
When the user select in this order:
C>B>A I will show the color blue....
based on different user select order, it will show different color....
But the question is, when I add more and more textfield, how can I implement this logic?
First, I design to have an array , when the user select one textfield, I store the textfield id to array, when user select the second one, I will store in the array, until the user click confirm, I read back the array to display the color....
But I think it will become very big & messy when more and more textfield is added, any better ideas? Thank you.
It's a bit of a hack, but what I'd be inclined to do is store the selections in a string that gets appended to each time (starting with empty string of course), trimming to the rightmost x characters. Then you can do a simple switch/case statement to determine the color. For example (C# fragments, sort of):
string selectStr = string.Empty;
void Select(string btn) {
selectStr += btn;
selectStr = selectStr.Remove(0, btn.Length - 3);
}
void Confirm() {
switch (selectStr) {
case "ABC" : /* make red */ break;
case "BAC" : /* make green */ break;
// etc.
}
}
I have the following code which allows the columns in my table to sort by ascending or descending order.
protected void setSortColumn(GridPanelColumn gridPanelColumn, TableColumn column) {
table.setRedraw(false);
// check if already selected
if (sortGridPanelColumn != null && sortGridPanelColumn == gridPanelColumn) {
// toggle sort order
sortAscending = !sortAscending;
} else {
// set new sort column
sortGridPanelColumn = gridPanelColumn;
sortAscending = false;
table.setSortColumn(column);
}
// set sort direction
table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
// refresh table
tableViewer.refresh();
table.setRedraw(true);
}
The only problem is that when the user clicks on the column header to sort, the arrow causes the column name to dot out (ex: Ccy..^ ) instead of (CCy1 Amount). Is there any way to turn off the showing of the arrows? I would rather not have to bother with resizing my grid columns just to accommodate for the arrows so that the dots don't form..
Any ideas on how to do this?
Simple! Just do not do
table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
When you call this method, you're just telling SWT which image to use. Without it, the sorting still works, but the arrows do not show.