I've created a C# Windows Forms application in .NET. It has a main form. Main form has a ListView control with four columns as below:
First Name
Last Name
Age
Gender
I populate the list view with 1 row with following values
First Name - Rasik
Last Name - Bihari
Age - 32
Gender - Male
Here is the screenshot:
I'm trying to test its accessibility for specially-abled users through JAWS screen reader tool. The issue is that whenever I select one of the rows it reads only the value of all the column values one by one. It doesn't read the header text along with it. My expectation is that it should read like -
First Name : Rasik
Last Name : Bihari
Age : 32
Gender : Male
JAWS support some keyboard shortcuts to have this behavior explicitly. Like if you press Insert + Ctrl + 1 then it will read the value of first column like this -
First Name : Rasik
If you press Insert + Ctrl + 2 then it will read the value of second column like this -
Last Name : Bihari
I want this behavior by default so that as soon we select a row in the ListView control i.e. it should read the entire row in 'column header text' : 'column value' pairs.
Does anyone has any clue on this if there is any property of listView control which need to be set or any setting in JAWS which can be of help?
If you are looking for a sample behavior then open Visual Studio -> Go to Debug Menu -> Click Attach to Process menu item. In Attach to Process window there is a group box Available Processes which shows the list of all available processes to which you can attach your code. It is also a ListView control. When I run JAWS with Visual Studio, on this window it reads all the column header text and column value pairs one by one when I select a row by mouse. I expect the same behavior for my application also.
But on the same machine JAWS is behaving differently for my application.
I was able to figure this out myself. There was no additional coding required to achieve it. Actually JAWS by default suppresses this reading behavior through its configuration. You need to configure JAWS explicitly to read the rows of a list view in <Column Header> - <Column Value> fashion.
When your application is running and the current focus is on a list view control on the form being displayed, press JAWS KEY + F2. It opens JAWS manager popup showing a list of what all items can be configured. Choose second option Customize ListView and press OK (Refer screenshot):
On the Customize Headers window you will see that currently Ignore radio button is selected (Refer screenshot):
Change the radio button selection to the appropriate option to alter the screen reading behavior for ListView control.
The most irritating issue is that this configuration needs to be done separately for every list view control appearing in your application. There is no centralized mechanism to configure it in one go for your entire application.
Note: Since by default JAWS is configured to read only column values, this means that it is appropriate for specially abled users. Freedom scientific must have researched around it as reading the column headers might be extraneous/trivial information which is not desired at once.
Also, if the specially abled user wants to read the column headers then JAWS KEY + Ctrl + Column Header Index keyboard shortcut is always available to read it in that format.
Note: Different screen reader tools like Thunder, NVA behave differently while reading a ListView.
Related
I'm in the process of creating a front-end Windows Forms application, which will have multiple uses. One of those uses will be to allow the end-user to manage the contents of a database table.
At the moment, my form contains a DataGridView object which uses a DataTable as its source. That datatable is populated from a stored procedure which selects every row from the table based on criteria specified by the end user. I want to put code into the DataGridView which will look at the row that's been selected by the user, and will populate a series of text boxes with the details from that row.
I want to avoid hard-coding a text box for each column in the DataGridView, since it's highly possible that in the future I might add columns to the underlying stored procedure. Therefore, my plan is that the first time the user selects a row, the application would dynamically create a text box for each column, size that text box appropriately (both height and width) and add the appropriate labels.
So far, the code I've written creates a brand-new DataTable, and adds columns to store the following information about each column in the DataGridView:
The actual name of the DataGridView column;
The name that I wish to give to the associated label;
The text that I wish to assign to the associated label;
The top and left positions of the associated label;
The name that I wish to give to the associated text box;
The value that I wish to display in the associated text box;
So far when the user initially clicks on a row, everything is working well: the text boxes get created in a vertical column, with the associated label to the left of each text box and the appropriate value displayed in each one. Each text box has its width dynamically set based on the contents of that text box so that everything can easily be seen.
The difficulty comes when the user changes from one row of the DataGridView to another. The code that runs to create each control looks like this:
if (pnlManageJobManagerOutcomes.Controls.Contains(txtCurrent))
{
pnlManageJobManagerOutcomes.Controls.Remove(txtCurrent);
}
if (!pnlManageJobManagerOutcomes.Controls.Contains(txtCurrent))
{
pnlManageJobManagerOutcomes.Controls.Add(txtCurrent);
}
When the code first runs, all seems to be fine. However, if it gets fired a second time (at which point it should remove and re-create the control) it doesn't seem to detect the prior existence of the control and simply creates a second copy of it in the form.
For information, the form I'm building has multiple uses which are dictated by a series of buttons. Therefore, I'm creating the controls for this particular use inside a Panel (pnlManageJobManagerOutcomes). I'm completely stumped as to why the code doesn't spot the existence of those controls during subsequent executions.
TIA
I've figured out a way to do it, which may seem to be clunky but which seems to work.
Since it doesn't appear that I can check to see whether the Panel I'm working with Contains the field name, I've written a method which will loop through the controls in that Panel and return a count of the number of instances of that control in the Panel's Controls array. If the method returns a 0, this means the Control doesn't exist in that Panel and I can go ahead and create it.
I have DataGridView with Four columns.
1st column contains "Text",
2nd, 3rd and 4rt column contains Bit Image.
Now this image are conditionally get rendered inside the columns and if condition is false it will contain "null" i.e. nothing in that column. However this blank column is part of Tab key, means when user navigate using Tab key in the grid, cursor traverse across all the column irrespective of column contains anything or not in it.
I would like to traverse cursor only to the column which contains value with in it. So how can I achieved this?
Following are the approaches I tried -
1. I filled all the column with respective images by removing the condition. now all the columns have some image in it, but I am unable to Enable/Disable those image conditionally. and because of that this all images are actionable and user can perform the operation which it should not. And when I applied Visible true/False so that it will apply across all rows for that column index and resultant the valid cell also invisible.
2. I placed button with in that column and tried to applied that bit image to that button and tried to enable/disable button as button has the property. but Bit Image is not getting applied to button and when I assign gridCell.value = btn; it will throw error since it is not text it is complete control. So not valid approach.
3. Using ProcessCmdKey() Method group, but not acceptable approach, though it has started performing as expected.
Please find the screen shot for more detail.enter image description here
Layout images and behaviord0sAI.png
I am writing a plugin for Revit 2014. One of its features placing a vertical column by the user. Revit API allows placing family instances by the user with the method PromptForFamilyInstancePlacement, which is what I'm using, like so:
//PillarSymbols is a list containing symbols of various columns available, loaded previously from a file
FamilySymbol symbol = PillarsSymbols.Single(x => x.Kind == selected.Kind).Symbol;
_commandData.Application.ActiveUIDocument.PromptForFamilyInstancePlacement(symbol);
This code enables Modify | Place structural column tool in Revit application. It works as desired, but does not allow the user to switch between Vertical Column and Slanted Column. This option is set to whatever it was set before running the code above.
I have tried to set the symbol parameters before running PromptForFamilyInstancePlacement using:
symbol.get_Parameter(BuiltInParameter.SLANTED_COLUMN_TYPE_PARAM).Set(value);
but get_Parameter() above returns null.
Is there a method to set column type to Vertical Column, before prompting the user to place the column? Also is there a way to pre-set column height?
Unfortunately you can't preset the column height but you can adjust the free end of the item created directly afterwards. You should be returning a FamilyInstance, so if you grab it again then you can adjust the free end of it.
You may be able to prompt the user to place the correct symbol by cycling through the symbols in the family. Try the snippet below and check to make sure that the symbol produced is the one that you want before placement:
FamilySymbol familySymbol = family.Symbols.ForwardIterator().Current as FamilySymbol;
I have created a SharePoint list that has a lookup column to an external list. I also have instructed SharePoint to display several secondary columns that are related to that primary external lookup column in my list as well.
The problem is that after I programmatically add a new SPListItem to my list and set the SPLookupValue for the primary lookup field (which works fine) when I go to the list view in my SharePoint portal I see the value in the primary field but when I click the green "refresh data from external list" icon in the column header to load the data from the external list into the secondary fields I get the following message.
Refresh successful.
0 item(s) were refreshed.
0 item(s) could not be refreshed. Contact your system Administrator.
In addition, when I try to edit the SPListItem the value that displays in the primary external lookup column (which should be a valid value) I am greeting with the message displayed below the textbox that reads:
"No exact match was found. Click the item(s) that did not resolve for more options. You can also use Select button to choose External Data."
When I click on the icon to select the external data, I get the pop-up window/dialog that allows me to select items from the external list. All of the data displays properly. There are no errors. But when I actually select one of the rows and click "OK" I get the same red error message saying that "No exact match was found...".
I'm guessing that there is something wrong with my External Content Type, Bdc Model, Specific Finder method that is responsible for retrieving the data for a specific entity result but I'm just not sure how to identify exactly what is wrong.
OK. So I figured out the problem.
I had created Identifiers for ALL of my entity's properties instead of just creating identifiers for only the properties that makes the specific entity unique! I had created identifiers for properties that had null values and others that were of type DateTime that do not at all uniquely identify the entity. As a result, when trying to perform a refresh on the external list data, it was trying to retrieve the external data for each of the individual list items with the assumption that every single column/field in the external list was part of the unique identifier for a particular list item. Obviously that prevented the data from refreshing correctly.
How can I repeat a group header on each page? I have some group that has a lot of rows and thus could not be placed in one single page. I want the group header to put on each pages. I can repeat report-header to repeat on each page but dont know how to repeat group header. Also I am working on rdlc report (not rdl) report.
Here is the solution.
When you don't have grouping in your report, to repeat the headers on other pages is easy. Click on Advanced Mode of property grid - check the property. Go to right panel and set RepeatOnNewPage on True and keeptogether 'After'. It is easy.
If you have grouping then it gets a little complicated:
Select the tablix properties and select "repeat header rows on each page".
Click on row groups and select "the top most static" and now click - RepeatOnNewPage -True and KeepWithGroup After.
In VS 2005 you can click on the header and see a property in the property grid called RepeatOnNewPage. Just set it to true. (click on the far left panel after clicking on a control in the header)
I had the same issue. I found a solution and it works like a charm.
First, you need use the Advanced Tablix Member Properties. The Advanced Tablix Member Properties become available when you click the little arrow on the right side of the grouping pane.
Then, you need to change the proprieties of the Tablix Member like mentioned in the picture.
Fore more details, you can check the link below.
https://www.sqlchick.com/entries/2011/8/20/repeating-column-headers-on-every-page-in-ssrs-doesnt-work-o.html
check out this url
[How to repeat table's header rows on each page in Reportviewer11 with Visual Studio 2010
ie
Open up the the RDLC file in the xml editor (right click on the file in VS and select "Open With.." and then "XML Editor")
Search for the entry (if you have only one table you can emit this step)
<TablixRowHierarchy>
<TablixMembers>
In the first node (if your headers are on the first row in the table) add the following entry true, so the entry will generally look like this:
<TablixMember>
<KeepWithGroup>After</KeepWithGroup>
<RepeatOnNewPage>true</RepeatOnNewPage>
<KeepTogether>true</KeepTogether>
</TablixMember>