I have two columns in my NSOutlineView. One is a Text and image cell (similar to the class in the DragNDropOutlineView Apple sample code). Next to that is a custom NSCell subclass called "XFToggleCell" that is used to display a visibility icon (eyeball) that you can toggle on and off (just like Photoshop).
The XFToggleCell supports mouse tracking/dragging (again, just like Photoshop) so you can click one eyeball, then drag down to show/hide multiple items at once. In the text and image cell, I display the text in gray when the item's hidden, and black when it's not.
Almost everything is working fine. When I click an eyeball (XFToggleCell), it's image clears out and my model object becomes hidden. However, the adjacent text and image cell's font doesn't become gray (it doesn't update) until I click the toggle cell again...and when I do, the coloring of the image and text cell's text is always opposite of what it should be (when the visibility is clicked on, the text goes gray, and vice versa).
I determined that the reason this is happening is because the text and image cell is being redrawn before the value of the toggle cell is changed. As a result, its display is always "one click behind". The sequence goes like this:
I mousedown on column 1's toggle cell.
The text and image cell in column 0 is redrawn.
The object value for the toggle cell in column 1 is changed.
The toggle cell in column 1 is redrawn.
If I can force a redraw of the text and image cell in column 0 as step 5 above, I should be good to go.
How do I force an update to the drawing of column 0's text and image cell as a result of clicking on column 1's cell?
Here's the implementation of what I think is the key method...In my XFToggleCell.m, which is in column 1:
- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
{
.
.
.
...do some stuff...
.
.
.
//Here's where I change the cell's object value, causing the cell to be redrawn.
//This part works fine.
[self setObjectValue:([self.representedObject newState]) ? self.image : nil];
.
.
.
//Why doesn't this next line update the adjacent cell?!?!?!?!?
//Column 0 contains the text and image cell I'm trying to update
[controlView setNeedsDisplayInRect:[(NSOutlineView *)controlView frameOfCellAtColumn:0 row:thisRow]];
}
return YES;
}
Well, I'm not quite sure why, but calling
[(NSOutlineView *)controlView setNeedsDisplayInRect:[(NSOutlineView *)controlView frameOfCellAtColumn:col row:row]];
didn't work when I put it at the end of
-(BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
in my XFToggleCell class.
So I tried adding
[outlineView setNeedsDisplayInRect:[outlineView frameOfCellAtColumn:col row:row]];
at the end of my
-(void) outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
method in my NSOutlineView datasource and it worked. Not sure why, but this is how to do it. If anyone can shed light as to why it didn't work calling essentially the same thing in the cell, I'd appreciate the info.
Related
In my (not binded) DataGridView some cells are editable, and some are not.
When I click on an editable cell the focus goes there and i can write anything.
Then, if i press the key TAB the focus goes to the next cell.
But if the entered value is not valid, i can check the value from the event Grid_CellValidating and cancel the change using e.Cancel = True . If I do so, the focus stays in the same cell waiting for a valid value, instead of changing the current cell.
Until here all works as expected.
What I need now is, from a new modal window where I can select a value, set this value to a cell of the grid in the parent form and close the modal window.
This works, but I don't want just set the value to the cell. I want also to set the cell in "editing mode". I mean by "editing mode" that state where the cell content is selected and if you try to change the value, the event Grid_CellValidating fires and if the value is not valid, the logic in the Grid_CellValidating event can check it to decide if it's valid or not...
I didn't succeed with that.
This is the code I'm trying to use to make it work.
myGrid.Rows(myGrid.Rows.Count - 1).Cells("EID").Value = 1
myGrid.Focus()
myGrid.CurrentCell = myGrid("EID", myGrid.Rows.Count - 1)
myGrid.BeginEdit(True)
But this definitely does not work.
In fact, the focus is not even on the Grid. I can see the value 1 in the cell but the focus is not there. For example, if I press the key TAB I can see that the focus is on another control, not in the Grid.
What I expect is: If the value 1 is not valid, the event CellValidating fires and do the work...
Do you know what should I do to get the behavior I need?
I have very simple grid which contains a lot of data - so my scroll ball is quite narrow. I edit data in cells. Left to my grid there is picture with coordinates points. I wish this behavior: when I click on coordinate point I want to go to corresponding grid row. They are related by id(id row = id point div). How can it be made?
Also when I edit grid in the middle and bind coordinates of new point to row(by using store) - the grid gets automatically reloaded after store is updated - and scroll gets to the top. How can I track last edited row in the middle of the list so I can auotmatically focus on it? Thanx in advance.
use the focusRow method (http://docs.sencha.com/extjs/4.2.3/#!/api/Ext.view.Table-method-focusRow) to scroll where you want, for example :
yourGrid.getView().focusRow(10);
To disable the 'scroll to the top" effect when you reload the grid, set preserveScrollOnRefresh to true on the viewConfig of your grid (http://docs.sencha.com/extjs/4.2.3/#!/api/Ext.view.Table-cfg-preserveScrollOnRefresh).
I have a ComboBox implemented with an auto-completion system. My ComboBox contains more than 100 items. When users are typing text in, the auto-completion system opens the dropdown list and highlights the most relevant item. Moreover, when the dropdown list is expanded, all items are available (no filters). But the most relevant item is always at the bottom of the dropdown list.
I would like it to be in the middle, if possible. One item can have the same reference but another type than another one, that's why I need to see most of them in my dropdown by placing them in the middle.
Any idea ? It's not really important but kind of useful for them. Thanks !
Update :
Here's my ComboBox with the open dropdown. Sorry about that, I had to blur its elements. As you can see, the user starts writting the reference in the ComboBox. The autocompletion works fine, but the corresponding item is found at the end of the dropdown list (in the red frame), almost out of bounds.
I wish it would be highlighted in the middle of my dropdown list instead of so far below.
Your item search may work well, but your list isn't visually filtered, which means it's size always remains the same.
It's scrolled into view, by the wpf system, but still displaying all other items around the relevant one. The reason why it's at the bottom is because wpf Scrollviewer just finished scrolling the item into view and sees no need to scroll it further into the middle.
You could use the CollectionViewSource class. Why ?
It's simple to use, will keep your viewmodel data as it is, and you would have your relevant completion item at the top. It can be obtained by GetDefaultView(..)
Let's say you have a viewmodel flag "IsHidden", stating that it's content does not match the user input:
ICollectionView cv= CollectionViewSource.GetDefaultView(myComboBox.ItemsSource);
// switch filter on
cv.Filter = obj => (obj as myViewModel).IsHidden == false;
// switch off
cv.Filter = null
I have a grid, in which some rows with data are "inherited". That is, there are some parent rows and child rows. Child rows have the id_inherit field set to the id of the parent row. The grid is editable. Now I want to add some functionality which makes it possible to analyze changes in all child rows. If some value in some cell is different from that in the parent row, then I want to change the background of that particular cell in the inherited row. I want to do these analytics on the fly: in other words, I want to make it when the user hits the button. Now, I parse my grid rows like this:
var store = Ext.getCmp('grid').getStore();
store.each(function(record,idx){
if(record.get('id_inherit')!=0){ // grid row is inherited
// here I want to compare values in all cells of this row
// and the parent row, whose `id` is equal to record.get('id_inherit')
// if values are different in a particular cell of the inherited row, then
// I want to change its background color
}
});
EDIT
Now, without any comparison, I just try to change the cell color of all inherited rows, but it does not work. I do it like this:
store.each(function(record,idx){
if(record.get('id_inherit')!=0){
grid.getView().addRowCls(idx,'red');
// I guess I should have used addCls instead, but
// I do not know how to target a particular cell inside this record
// and change its class correctly
// but of course, I know column names and indices
}
});
And red style is defined like this:
.red {background-color: red !important;}
But it is not working. If I knew how to change the cell color dynamically, I could do all the other routines - comparing with parent rows, etc.
EDIT
I tried practically all solutions posted at StackOverflow and which seem to relate to some extent to my problem, but none of them work. What I want to stress again, is that I need to change the background color of a particular cell - NOT of the entire row and NOT of the entire column. And I want to do it on the button click - NOT inside the render function.
EDIT
I consulted this article ExtJS 4 Grid Change Cell Color , but the author manupulates the DOM of the selected row, and does it like this:
var selection = grid.getView().getSelectionModel().getSelection()[0];
var dom = (grid.getView().getSelectedNodes()[0]);
tds = Ext.get(dom).select("div");
Ext.get(tds.elements[evt.target.offsetParent.cellIndex]).addCls('black');
But in my case, where I iterate through the grid store, I do not know how to get to the dom of the current record, then select the div and add a custom class.
EDIT
Well, I tried thousands of tricks, but nothing works at all. If someone could advise me on how to parse a grid record to get to the cell HTML-structure, I would mark this advice as an answer. What I now know, inspecting the DOM structure, is, for example, that one of my cells has this CSS class x-grid-cell x-grid-cell-73892 x-grid-cell-last. What makes it unique is this part: x-grid-cell-73892. So, I tried to do it this way
store.each(function(record,idx){
var div = Ext.fly(record).query('x-grid-cell-73892').select('div')
....
});
But this is not working. Who would have thought, that such a trivial thing - the most trivial that I can imagine - that is to change the background color of a cell on button click, has no simple solution. At this point I have no solution, in fact.
EDIT
Well, I did it myself. The trick was to use the getCell function:
var column=grid.columns[index],
cell=grid.getView().getCell(record, column);
cell.addCls('mycss');
Using reporting services and trying to hide a field placeholder value when it does not equal "View" The value is hyperlinked to a subreport and is located in a bordered textbox inside a tablix. If I use the visibility feature for the text box, I can hide the non-view hyperlinks with an expression, but it hides the entire textbox and the textbox borders go away for that cell--I really want them to remain and just show the empty cell. If, instead, I try to hide the value on the placeholder level, which does not present the visibility option, and I attempt to evaluate the expression for the placeholder value to Nothing or '' when it is not valued as "View" then I get a hyperlink dash display in the column where I think it's attempting to render an unvalued hyperlink, which I really don't want. I just want an empty, bordered textbox.
Any way around this?
One solution is to change the visibility of the textbox value like this
IIF(fields(View.value) = 'true' , fields(TextBoxVariable.value), " ")
note that " " at the end will hide your dash
Or you can put a rectangle in the tablix cell and set its border, the you can put a textbox inside of the rectangle and change the visibilityof the textbox easily
put you link action on placeholder properties: Action - go to subreport, then put hidden expression on textbox: IIF(Fields!NameFields="View", true, false)
it works for me.
I know this is an old post, but I recently ran into this same issue.
Remove the expression from the text box properties and add it to the expression box of the field (right-click on the field and instead of choosing Text Box Properties>Visibility, choose Expression from the context menu). This will replace the field with an expression and the border lines will still exist.
Here's what I added to my expression:
=IIF(FORMAT(CDATE(Fields!ApprovedDate.Value),"dd-mm-yyyy") > "01-01-1980",Fields!ApprovedDate.Value," ")
I think that the easiest way to get rid off this hyperlink dash, is to change the font effect of the text-box. Just select Font-tab from text-box properties and from there, click fx-button of Effects and put somethin like this as expression:
=IIF(Fields!YourValueField.Value is nothing, "None", "Underline")