Say I have a tableview with 10 rows, and inside each row are two labels (labelA and labelB).
If I wanted to change the text of labelB in row 3, what would be the call to do that?
Thanks!!
Found the answer and putting it here for future reference incase anyone else runs into this.
Here is the answer code to my question
tbl.data[0].rows[2].children[1].text
tbl.data[0] = Data for the Tableview
rows[2] = Goto row 3 (rows start at 0)
children[1] = Goto the second child (again the first label would be child 0 and the second would be child 1)
text = the actual text of the label
Related
I am writing an UI test case, in which I need to perform an action, and then on the current page, scroll the only UITableView to the bottom to check if specific text shows up inside the last cell in the UITableView.
Right now the only way I can think of is to scroll it using app.tables.cells.element(boundBy: 0).swipeUp(), but if there are too many cells, it doesn't scroll all the way to the bottom. And the number of cells in the UITableView is not always the same, I cannot swipe up more than once because there might be only one cell in the table.
One way you could go about this is by getting the last cell from the tableView. Then, run a while loop that scrolls and checks to see if the cell isHittable between each scroll. Once it's determined that isHittable == true, the element can then be asserted against.
https://developer.apple.com/documentation/xctest/xcuielement/1500561-ishittable
It would look something like this (Swift answer):
In your XCTestCase file, write a query to identify the table. Then, a subsequent query to identify the last cell.
let tableView = app.descendants(matching: .table).firstMatch
guard let lastCell = tableView.cells.allElementsBoundByIndex.last else { return }
Use a while loop to determine whether or not the cell isHittable/is on screen. Note: isHittable relies on the cell's userInteractionEnabled property being set to true
//Add in a count, so that the loop can escape if it's scrolled too many times
let MAX_SCROLLS = 10
var count = 0
while lastCell.isHittable == false && count < MAX_SCROLLS {
apps.swipeUp()
count += 1
}
Check the cell's text using the label property, and compare it against the expected text.
//If there is only one label within the cell
let textInLastCell = lastCell.descendants(matching: .staticText).firstMatch
XCTAssertTrue(textInLastCell.label == "Expected Text" && textInLastCell.isHittable)
Blaines answer lead me to dig a little bit more into this topic and I found a different solution that worked for me:
func testTheTest() {
let app = XCUIApplication()
app.launch()
// Opens a menu in my app which contains the table view
app.buttons["openMenu"].tap()
// Get a handle for the tableView
let listpagetableviewTable = app.tables["myTableView"]
// Get a handle for the not yet existing cell by its content text
let cell = listpagetableviewTable.staticTexts["This text is from the cell"]
// Swipe down until it is visible
while !cell.exists {
app.swipeUp()
}
// Interact with it when visible
cell.tap()
}
One thing I had to do for this in order to work is set isAccessibilityElement to true and also assign accessibilityLabel as a String to the table view so it can be queried by it within the test code.
This might not be best practice but for what I could see in my test it works very well. I don't know how it would work when the cell has no text, one might be able to reference the cell(which is not really directly referenced here) by an image view or something else. It's obviously missing the counter from Blaines answer but I left it out for simplicity reasons.
I have a spreadsheet with a picture. I don't know the size of the picture (it may vary).
I want to to get the last row of the picture in a variable (I want to leave a blank row to the bottom of the picture and start filling data in the next row). Could you help me figure out the syntax?
I can't even figure out how to get the picture into a variable..
I was able to do this with the following code:
Dim testPic As Object
For Each testPic In ActiveSheet.Pictures
h = testPic.Height
cellHeight = Cells(ImageTopRow, ImageLeftCol).Height
nRows = h/cellHeight
Next
But:
a. I don't need a foreach, there's only one picture in the collection, I just can't figure out how to get the first one.
b. There should be an easier way, right?
Thanks,
Li
Dim pic As Shape
Set pic = ActiveSheet.Shapes(1)
MsgBox pic.BottomRightCell.Row
will show you the cell's location of the right bottom corner, ie
Hope this will help.
"ActiveSheet.Shapes.Count " - this helps you count the number of pictures in the active sheet
"ActiveSheet.Shapes(1)" - you can just use this if you only have 1 Photo or if you want the bottom right of the 1st photo
Code:
click to view the code Dim pic As Shape
Set pic = ActiveSheet.Shapes(ActiveSheet.Shapes.Count)
'Determines the address on the bottom right of the picture
lLast = pic.BottomRightCell.Address
'Selects the Bottom right cell of the Image/picture
Range(lLast).Select
On a form I have 4 MSFlexGrids.
The top grid contains dynamic data, which updates once in a while.
The user can enter data in the cells of the 3 other grids.
The data which is used to fill the top grid is received via a Winsock control, processed, and then the results are written into the appropriate cells using .TextMatrix(intRow, intCol) = strData
This works fine. The data is updated flawlessly, and the user can enter his data into the other 3 grids without any problems.
The problem occurs when I want to change the background color of some cells in the top grid.
On rare occasions the received data is very important, and the background color of the corresponding cells should change color.
I change the color of the cells with the following code:
With grd
For lngRow = 1 To .Rows - 1
'default background color
lngBack = vbWhite
'check for important values
If Val(.TextMatrix(lngRow, 1)) >= lngMax Then
'important color
lngBack = &H3040FF
End If
'select whole row
.Row = lngRow
.Col = 0
.RowSel = lngRow
.ColSel = .Cols - 1
'set the background color of the selected row
.CellBackColor = lngBack
Next lngRow
End With 'grd
The problem with this is that when the user is entering data in the other 3 grids, and the background color of a row in the top grid is changed, then the focus moves to the top grid, and the user has to enter his data anew in the grid where he was working.
Is it possible to change the background color of a cell or whole row in a MSFlexGrid without moving the focus to that grid?
So far I could not find a solution to the problem itself.
I created a work around though :
I created an enum containing a value for each grid:
Public Enum ActiveGrid
enuSystem = 0
enuTel = 1
enuRLN = 2
enuRood = 3
enuData = 4
enuCircuit = 5
End Enum
Whenever a grid gets the focus I save the corresponding enum value in a form level variable.
After coloring the required cells in the first grid I return the focus to the grid which last had it.
The user is not editing in the grid itself, but in a textbox which is laid over the cell, so there is no real problem with the grid losing the focus.
When you look closely though you see the focus leave and return quickly.
For now I will accept this work around, and its minor glitches.
Maybe in the future I can come up with a better solution, or anyone else has a better suggestion?
I'm working with a MSFlexGrid control in VB6, but I'm also having some problems retrieving the ColPos property for merged columns. The grid that I've generated looks something like this:
-----------------------------
| 8/17/2010 |
-----------------------------
| Column 1 | Column 2 |
-----------------------------
The first row is fixed and the two columns are merged, so both columns contain 8/17/2010 in the first row.
During the Click event, I'm positioning a text box over a cell in the second row, and when I set its Left and Top properties using the FlexGrid's ColPos and RowPos properties, I end up with the textbox positioned over column 1. This happens even if I clicked in column 2.
I've checked the Col property, and it's correctly set to 2 after clicking in the second column, but ColPos(1) and ColPos(2) both return the same value, which is the distance from column 1's left edge to the left edge of the control.
When merging is disabled on the flexgrid, the problem goes away, but I'd rather leave it on since it makes the grid a bit more readable.
Is there any way to retrieve the correct position of the selected column when another cell in the column is merged with another one, or do I need to calculate the column position manually?
Haven't found a way to do it through the control, but here's a function that I put together that does the trick. It counts backward from the selected cell until it reaches the leftmost cell it's merged with, and then adds the widths of the merged cells to the first one's position. Probably could be cleaned up some, but this does work.
Private Function RealColPos(Col As Integer, grid as MSFlexGrid)
With grid
Dim i As Integer, merged As Integer
i = Col - 1: merged = 0
Do While .ColPos(Col) = .ColPos(i)
merged = merged + 1
i = i - 1
Loop
If merged > 0 Then
RealColPos = .ColPos(Col - merged)
Do While merged > 0
RealColPos = RealColPos + .ColWidth(Col - merged)
merged = merged - 1
Loop
Else
RealColPos = .ColPos(Col)
End If
End With
End Function
I'm working with some legacy code and need to change the background color of a row (and the font color) in a ListView in VB6 based on some criteria. I need to change the color of the row when the row is selected and not selected. I can change the font color of a non-selected row via the .Foreground property but I can't change the color in any of the other scenarios.
Check out this forum post. Here's an sample from the code which colors every other row:
'\\ loop through the rows to select every other row
For i = 1 To lvwBackColour.ListItems.Count
If (lvwBackColour.ListItems(i).Index Mod 2) = 0 Then
'\\ add a tick to the checkbox
lvwBackColour.ListItems(i).Checked = True
'\\ add the colour to the picturebox
'\\ See Here (http://msdn2.microsoft.com/en-us/library/aa230480(VS.60).aspx)
'\\ for information about the Line method
picBG.Line (0, i - 1)-(1, i), &H4000FF, BF
'\\ update column four caption
lvwBackColour.ListItems(i).SubItems(3) = "Hidden column value = 1"
Else
'\\ remove the tick from the checkbox
lvwBackColour.ListItems(i).Checked = False
'\\ reset backcolour to white
picBG.Line (0, i - 1)-(1, i), &HFFFFFF, BF
'\\ reset the Column Four caption
lvwBackColour.ListItems(i).SubItems(3) = "Hidden column value = 0"
End If
Next i
'\\ set the listview to use the picturebox image
lvwBackColour.Picture = picBG.Image
Here's the link to the msdn article which talks about the Line method.
The background color of selected rows is controlled by the system. You cannot change it to anything else.
If you have to be able to change the background of the selected rows, you will need to custom draw the listview -- which, to be honest, is too much of a pain to seriously consider :)