How to Disable Tab functionality inside a grid in WPF - wpf

My requirement is rather a tricky one (it seems to me).
I will explain the scenario.
I have a DataGrid. In the DataGrid, I have two columns in which I have a grid in every cell of these two columns, inside of which, there are two comboboxes - the purpose being to switch the visibility based on some conditions.
When we select a value in the combobox, the combobox itself, plus some other controls in some other columns will get disabled (requirement of the pjt). Now there is also, another requirement like, Tab should not be allowed in the cell which has disabled controls - say disabled combobox.
We are setting the controls as Enabled or Disabled based on a selected value from the combobox. So, since we are applying the disabling property on the control level, and the IsTabStop property is on the cell level, I am not able to restrict Tabbing in the cells having disabled control.
Any thoughts?

Don't use a DataGrid.
DataGrid's are awesome for read-only stuff, but they seem to suck for doing any kind of interesting editing. After well over a week of fighting with it, I've given up on it.
Right now I'm looking for a replacement, which may end up just being a scrollable stack panel with manually added controls.
WPF: Is there a "ListBox" without the ability to select items?

Related

Silverlight: Individual visibility of a RowDetailsTemplate for each data row

I'm trying to achive displaying the RowDetailsTemplate of a Silverlight DataGrid depending on a bool Property, bound to a CheckBox Control's IsChecked Property. Insinde of my RowDetailsTemplate there is a single custom UserControl, containing further Controls.
Since the DataGrid only allows a global setting (RowDetailsVisibilityMode) Some code-behind is needed. I've implemented a solution based on Rorys Reply (and using a behaviour-technique) which actually works.
Unfortunately, The DataGrid doesn't remember the individually shown or hidden Rows on sorting. The checkbox remains selected, but the Row collapses. Further, no event like "OnAfterSort" or something similar seems to exist, where i could "Refresh" the visibility settings in a loop.
Another idea was to bind the Visibility of my custom Details-UserControl to the CheckBox bound value. This actually works (when settings RowDetailsVisibilityMode to "Visible"), but I'm not able to get rid of this weird behaviour: When the CheckBox is checked, the Detail Template expands and the detail UserControl appears. Nice. When the CheckBox is unchecked again, the UserControl disappears (Visibility is set to Collapsed) but the Row doesn't collapse and the blank space remains (as it would be set to Hidden not Collapsed).
Do you have any ideas?
I hope it's ok I didn't post any code samples, the implementation is pretty easy and I believe that the problem doesn't actually lie in a coding mistake i made. You can setup a simple DataGrid quickly like in this perfect MSDN Example. Starting from here, it's easy to test both described behaviours!
Really big thanks in advance,
- Thomas

WPF Datagrid deselects row when control is disabled

I have a program in which a user selects a row in a Datagrid and then clicks a "Start Recording" button. While "recording" is happening, they are not allowed to change the value selected in the datagrid, so I set IsEnabled to false. However, when the datagrid is set to be disabled, it deselects the selected row, which screws up any bindings I have to the datagrid's SelectedItem propery.
Is there any way to keep the datagrid row selected even though the control is disabled?
Edit: This does not happen in Windows Vista, but it does in Windows 7.
If you really want to 'record' actions but still keep visuals and interactions looking the same, why don't you just add a check to the event fired on selection to ensure that recording is not taking place and set e.Handled = true.
Alternatively you could set IsHitTestVisible = false and prevent them from taking actions in the control instead of disabling it outright.
Hope that helps.
Sorry I know this post is a little old, but I couldn't find another solution to this anywhere else.
It doesn't seem to be related to Vista\7, but to the Feb. release of the Toolkit.
You can set IsHitTestVisible = false as Jeff Wain suggests, but as Mike noted it doesn't appear different. Also, It doesn't disable Keyboard input.
My solution is to put the DataGrid in a Grid within the same row and column as a semitransparent gray rectangle (This will make them on top of one another). You have to put the rectangle in the Grid second to make sure it is on top of the DataGrid. When I want to 'disable' it I make the rectangle visible. This will make the list look dimmed and disable mouse inputs, but it still doesn't disable keyboard input.
To disable the keyboard I have to intercept 'PreviewKeyDown' and set e.Handdled = true. This will not allow anything else to be selected but will still do some interesting things when you tab to it (like tab no longer working). Perhaps setting it to not be a tab stop and not focusable will also fix this, but disabling selection is all I really care about.
IsHitTestVisible=false disables mouse inputs.
For disabling keyboard inputs set Focusable=false.
Both should be set via a style in ElementStyle and/or ElementEditingStyle for builtin datagrid columns inorder for the child control (textbox, checkbox, etc) to not accept input.
You'll most likely have to use a trigger in the style and bind it to some IsRecording value.
Also you could, in the same style, change the appearnce of the "disabled" controls by setting their Opacity=0.4, this gives somewhat of a disabled feel to them.

Determine who has focus in WPF Window

We are using WPF and have a window derived from a DockingLibrary. This window has a grid with multiple items in it, one being a WPF datagrid. We are using the M-V-VM pattern. When this windown is created and shown, none of the rows in this datagrid are selected. We can set the row to display as highlighted by doing something like:
SharedWindow.ShipmentWin.shipmentDataGrid.SelectedIndex = 0;
This causes the first row in the datagrid to be shown as highlighted. But, and isn't there always one of these, this row is not Selected nor does it have Focus. I tried setting IsSelected and Focus on this row as in:
SharedWindow.ShipmentWin.ShipVM.IsSelected = true;
bool focused = SharedWindow.ShipmentWin.shipmentDataGrid.Focus();
Am I going about this all wrong and is there some other way to Select the first row in the datagrid and set focus to it? Typically, when a datagrid is created, no row is selected until the user mouse clicks on the desired row.
Any thoughts would be greatly appreciated.
thanks!
Have a look at the FocusManager. It allows you the set the focus to another UI element via the SetFocusedElement method. Additionally, it allows you to determine the currently focused element in your application which is can get handy to debug focus issues. Snoop can be useful, too. It shows the currently focused element in the bottom status bar.
If you use the DataGrid from the WPF Toolkit, be prepared to find some bugs in relation to focus handling. Some have been addressed recently.
It's also worth understanding the difference between logical focus and keyboard focus, which are quite different animals. The .Focus() method sometimes only sets logical focus - which probably isn't what you want.
The documentation for the Focus method tells you that it will return true if the keyboard focus was set, and false otherwise.

Silverlight light dropdown

I have a Silverlight form that contains a Stack Panel (orientation = vertical) with 10 rows. Each row contains a TextBlock and Textbox control except the last row has a TextBlock and Drowdown.. At the bottom of the control are two buttons. Previous & Continue.
There are 10 items in the Dropdown. When I select a value from the Dropdown, only two of the ten items are showing up. I believe that the remaining items aren't displying because there's some sort of clipping effect going on. Fair enough.
Does Silverlight allow the dropdown control to display upwards (instead of the default down direction)? Will I have to override some rendering capabiliities before the dropdown is rendered to the control or is there a property that allows me to accomplish this functionality?
The Silverlight ComboBox auto aligns the dropdown popup to always be visible whenever possible.
all Popup based controls (ComboBox, AutoCompleteBox, DatePicker and TimePicker) all have this feature enabled.
So if there's not enough screen real-estate below the ComboBox to show the dropdown popup, it'll show up above the control.
The combobox nesting in the visual tree should not affect the dropdown popup auto alignment. The internal Popup control (inside the ComboBox) ignores the Visual Tree and is nested "above" the visual tree.
If you have specific issues, please share minimal and relevant XAML. Since Keith is on this thread, I think it's safe to say he'll log a bug if needed.

WPF Rendering performance

I have a WPF User control that binds to a DataTable and generates CheckBox and a masked EditBox for each row in a DataTable. I have several instances of this control on my form. The total number of CheckBoxes to be generated is over 200. I am seeing some rendering performance issues. The form loads with all of the static controls ( Text Boxes, Drop Downs) instantly, then several seconds later the CheckBoxes appear.
Any thoughts?
Thanks
Unless all the 200 items are visible on the screen, you should be using some kind of virtual layout that creates the visual tree only for the visible items. This will greatly improve your performance.
What is "generating" the checkboxes? You should be using an ItemsControl (or subclass) and binding the data that represents the checkboxes to it. Assuming you're doing that, then what you want to do is get that ItemsControl to use "virtualizing" by applying the VirtualizingStackPanel.IsVirtualizing property to the ItemsControl like so:
<ItemsControl VirtualizingStackPanel.IsVirtualizing="true" ... >
You might also want to turn on "container recycling" which will also help performance. This is also done with an attached property:
<ItemsControl VirtualizingStackPanel.VirtualizationMode="Recycling" ... >
Too many checkboxes surely cost a lot, if you look at templates of basic controls, they are also filled with lot of uielements.
I would suggest if you can divide your UI into Tabs or Accordins that will cause less visible items on one screen as well as it will help user navigate to items easily and faster as well.
VirtualizingStackPanel will help but if your binding isnt correct it may lead to unpredicted results.
Custom Control Template:
You can also create your own custom checkbox template with least UIElements, like simple rectangle filled with different color on IsChecked property trigger. This will eliminate few animations etc that can surely imporve your rendering performance. I believe CheckBox is least important when it comes to animating UI.
When you are sure that you will be using "Text" as content, then simply create template with rectangle to show filled/empty value and put TextBlock with template binding to Content.
Try to give fixed width/height to your checkbox, whenever you fix the height/width of your controls/containers, it becomes eaiser for layout manager to render them, rather then keep on calculating and adjusting items.

Resources