I have an ObservableCollection where T: INotifyDataErrorInfo. If I use the DataGrid in edit mode, and there is an error on the object, beside the exact column displaying a red border, the BACKGROUND of the ENTIRE ROW goes red.
I want the same functionality, but in readonly mode as well! The problem is, the DataGrid doesn't listen for ErrorsChanged event unless it goes into edit mode. How can I fix it? Do I have to subclass DataGrid? (I'd prefer not to, I'd rather use Styles or Behaviors) Where can I access the style of the row's background?
EDIT:
I've tried two new things:
I've subscribed to the datagrid's RowLoading event, and subscribed to the Row's Loaded and the DataContext's ErrorsChanged event from there (and unsubscribed on RowUnloading), and tried setting the VisualState of the row from these event handlers based on the validity of the DataContext. However, since setting the visual state doesn't change the actual state of the control so when it has to change states (for example on mouseover or selection) it changes back to Valid.
Using the trick I've learned from ComboBoxes (see here), I've tried to bind the DataContext to the DataGridRow.Tag, using row.SetBinding(DataGridRow.TagProperty,new Binding()); (since the Source is the DataContext and the path is the entire object), but absolutely nothing happened, like contrary to my earlier findings with ComboBox controls doesn't necessarily listen for Validation on Every DependencyProperty.
So it's getting less likely that there is a practical solution. Any thoughts?
Have a look at the following question, it might help
C# Silverlight Datagrid - Row Color Change
Related
When using a WPF application on windows 10 with a touchscreen we encounter an issue with the listview. When working with a mouse it works fine.
We have created a simple test-project, which is used to simulate the problem on windows 10 and can be found on GitHub. A ticket is also created on MSDN
In short below a summary of the technical setup:
We use a grouped listview, and for each group, a togglebutton and
another (inner) listview.
The inner listview uses an ItemTemplateSelector binded to an
Datatemplate selector, to choose an datatemplate.
There are 3 datatemplates (checkbox, numeric, text) that will be
choosen based upon the type property of the bounded model.
Each datatemplate has a stackpanel. The stackpanel in the text en
numeric datatemplate is wired to an PreviewMouseDown event.
Important, the stackpanel in the checkbox isn't wired to an event.
This works in general well, however sometimes, when touching the checkbox, the
PreviousMouseDown of another template is triggered.
I would expect that this behavior may not happen, is that correct?
We found a workaround (*) for this issue but we didn't find the root
cause.
Why is the event of another template triggered?
I'm starting to believe that this could be an issue with WPF Listview
and touch behavior?
(*) If we know that sometimes an event is triggered from a wrong template,
we verify every event whether that event is originated from the right template and if not we do nothing.
Below you can see when tapping quickly on the checkbox the clickevent get's triggered.
Below more details of the code:
The datatemplates and the selector
The grouped listview with the inner listview and the itemtemplate selector
Below the code behind and the handler for the PreviewMouseDown event
Below an overview of the steps we have been taken in order to resolve
it, but none lead into a solution.
Since WPF is supporting touch and a touch on a screen is also "translated" into a mousedown event, I don't see a problem why not using a previewMouseDown event on a touch screen. I also didn't find any offical documentation of Microsoft in not doing this.
Anyway, I could no longer reproduce the problem that a touch on listviewitem is invoking another previeuwMouseDown event of a template of another listviewitem in the list by ....
Changing the PrevieuwMouseDown event by a Touchdown event!
I am glad to find a solution, however based upon many online searches, I feel there are many issues with thouch on WPF and often it's is not clear what the rootcause is. Like in this case I found a solution by trial and error, but why the problem occurs when using previewMouseDown, is puzzling.
I am using a solution found here: http://malor.se/blog/?p=88 to add adorners to a datagrid text column. Works fine, except my adorner is binded to the underlying object, and it's failing to update upon source property changes. I can even bind the cell contents and the adorner text to the same property, and the cell content will reflect property changes while the adorner text doesn't. The adorner seems to refresh only when I do something to force a redraw of the cell, like resizing the column.
Is there a fairly non-hackish way I can get the adorner to refresh upon source property changes like other normal wpf controls?
Web searching seems to indicate that the adorner layer refreshes only on certain events, like a resizing, for the sake of performance I suppose. I'm now of the opinion that maybe it's not the best choice for my particular task.
I have buttons on my Silverlight page where the opacity is bound to one of two properties on my ViewModel. I'm using the button command that changes the properties, in theory to affect all buttons bound to that property, but the only control that gets affected is the button that initiates the command (any one of them).
Any ideas on why the additional bindings don't work?
The whole thing is actually a little more complex where the buttons are on a Control with the bindings as DependencyProperties mapping back to the VM, and the bound properties are going through a ValueConverter.
It sounds like you need to raise the INotifyPropertyChanged.PropertyChanged event for the properties that are changing. This will let the controls that are bound to them know that there is a change and that they need to come back and get the latest value.
I found the problem. The opacity binding wasn't working, but what was happening was the button was disabling itself based on the predicate I had set in the RelayCommand. It looked like the effect I wanted, but only affected the button being pressed because each button was bound to a seperate ICommand.
I changed it to remove change the binding from the OpacityProperty to the IsEnabledProperty, and removed the predicate from the RelayCommand declaration. It all works now as intended.
I don't know why the button would change to a disabled view when it checks the predicate (and finds it false), but never change back if the condition changes. Odd.
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
I have a custom text box control which raises a routed event when its TEXT property changes. This text property is data bound to a property on our view-model object.
When I place this control on a TabControl page or Expander control, it appears as if data binding only occurs when the control becomes visible for the first time, therefore I never receive any of the routed events until I swap to the tab the control is on or expand the expander.
Is there any way I can force data binding to occur before the control is shown?
Sounds like you relying on the data binding to genreate the routed event is the wrong approach. Instead you need to have your Model or ViewModel generate an event when the text is modified and then you watch this event from an appropriate place in your View.
Not very likely. WPF is a fairly efficient framework and won't do any work that it doesn't absolutely have to. This includes scenarios like data binding. Why bother exercising a collection for a control that might not ever be shown?