I have a form with some controls (say TextBox) which Text property is bound to some DataContext (say DataRowView).
I want to know if this row was filled correctly without any validation errors. I have found one possible solution. But I do not like it. It is not good to enum all the DependencyObjects on a form. Is there any way to enum only those DependencyObjects which was bound to this DataContext? May be some magic with BindingOperations...
How do you validate the input-data?
Maybe you could use a BindingGroup and then check it's Validation.HasError attached property.
Related
I have heard a lot about two-way bindings in WPF, but I'm not entirely clear on how to accomplish it or what it actually means.
I have a ListView with a bunch of items in it. When the user selects a new item, a TextBox in the application will change its text to display some property of the selected item.
But when the user changes the text in the text box I want the ListView item to be updated immediately as well. Is there any "two-way binding" magical WPF way of accomplishing this?
Mark's answer shows how to accomplish what you want, but you also asked more generally about "how to accomplish [two-way binding] and what it actually means."
One-way binding means that the binding target (e.g. control) will display data from the binding source (e.g. business object), and will update itself as the business object changes, but that changes to the control will not be propagated back to the business object. E.g. if the Person.Name changes from "bob" to "kate", the TextBlock.Text bound to the Name will change from "bob" to "kate" too.
Two-way binding simply means that not only are changes in the business object reflected in the UI, but changes made by the user in the UI are propagated back to the business object too. So now when the user edits the TextBox.Text bound to the Name, say changing "kate" to "edmund", WPF will set the Person.Name property to "edmund" as well.
To accomplish this, just set Mode=TwoWay on the Binding declaration. Some properties bind two-way by default: TextBox.Text, for example, binds TwoWay by default, which is why Mark's code doesn't need the Mode declaration. In addition, as Mark notes, by default WPF only propagates changes back to the business object when the control loses focus. If you have two UI elements bound to the same property, this can mean they appear out of sync, in which case you can use the UpdateSourceTrigger to force WPF to propagate whenever the property changes.
MSDN covers this in detail with some good clear diagrams: see Data Binding Overview in the WPF SDK.
If you haven't you'll need to implement INotifyPropertyChanged for your class that you're binding to.
Also, when you say you want the ListBox item to be updated immediately, you mean that you want it to change as you type in the TextBox. By default the TextBox.Text property updates its source when it loses focus, but you can change this by setting the binding UpdateSourceTrigger to PropertyChanged:
{Binding Source={...}, Path=Whatever, UpdateSourceTrigger=PropertyChanged}
What is the Type of the items in the ListView? To get the two way binding going the need you implement INotifyPropertyChanged...
This might help WPF event property changed?
A while back i had read a tutorial on data binding (maybe it was MVVM?) in Windows Forms. I've sense forgot everything and forgot the name of the tutorial.
What i would like to do is bind the enabled property of a button to a combox's selected item.
Logic: If combobox has selected item- enable button.
else disable button.
I'm aware of the combobox_textchanged and combobox_selecteditemchanged event and i would like to avoid using it if possible.
In WPF / MVVM, this is a UI issue that can be handled in a ViewModel class. In Windows Forms, you might also want to create a ViewModel class separate from your model class to keep UI concerns away from the Model classes. Either way, you can create a Boolean property like "IsActiveCustomer", or whatever it is in your case, in the object class you are binding to. Your property could either have a getter that returns a value based on the property that is bound to the combo box -- or you could use the combo box selected index changed or selected value changed events and set the Boolean property accordingly. Then, of course, bind the Enabled property of the button to the Boolean property. Probably need to know what you are data binding to in order to provide specifics (binding to object vs. BindingSource/table adapter, etc.)
I have a WPF TextBox that has it's text value bound in XAML. This works fine and, as expected, when the associated value is loaded to the field, it is formatted as desired.
My issue is when the user enters the text field to modify the value, I want to strip away the formatting, and display the raw underlying value.
To do this, I tried to set the BindingExpression.ParentBinding.StringFormat property, on the text boxes binding from within a GotFocus event. However, when I tried to set the StringFormat property to an empty string, I got the following exception:
Binding cannot be changed after it has been used.
So, after a control has been bound to a data model object, is there a straight-forward way that I can modify the string format of the TextBox? I'm willing to change how I format the value of the control, but the end desire is to strip the formatting of the data when it is being edited, and re-instating the string formatting once the user exits the field.
I would probably try it differently. It sounds like you are using the same TextBox for the formatted value and editing the raw value. It would be cleaner to use two different TextBoxes for View and Edit, or package it in a UserControl. Also, I would use two properties, e.g. RawText and FormattedText, and the UserControl would have DependencyProperties with bindings to both properties. The UserControl would automatically switch to the Edit TextBox. The question of "how does the automatic switching" work may be a challenge though. You probably need to use the GotFocus of the View TextBox as you mentioned, although it might not be a bad idea to have an actual Edit button that switches it for you.
I understand about switching to WPF. There is quite a bit of adjustment (aka learning) when switching to WPF. I would think of it as designing a form or control that is "fit for purpose". You don't have to create a new UserControl though. You could do something similar to StackOverflow where there is an Edit TextBox and then the View area, that would be equivalent to the Raw and Formatted values. You would control the Visibility of the Edit TextBox through a BoolToVisibilityConverter when you are in edit mode. Create a public bool IsEditing property on your ViewModel and bind that to the <EditTextBox Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}}" Text="{Binding RawText}" ...etc... /> After working with WPF for a while, you really appreciate data binding and it makes it hard to go back to plain WinForms (at least for me - not to say there aren't challenges though!).
I know how to prevent a property from being shown in the property grid by using this attribute
[Browsable(false)]
but I want to prevent this property from being browsed only when there are more than 1 object selected in the property grid.
I mean that when only one object is selected in the property grid this property will be shown but when 2 or more objects are selected this property won't be browsable!
Note: I haven't done it myself, but according to the documentation...
Have you tried BrowsableAttributes, documented here? In your selection code you could probably change the propertyGrid.BrowsableAttributes to reflect if it's a "solo" selection or "multiple" selection, and by tagging the variables accordingly, you should be able to have the display you're looking for.
This thread can probably help you!
I have a form with some textboxes in them that are bound to their properties in the VM through caliburn's automatic bindings. However if you type something on the textbox that does not make sense for the binding Caliburn simply does nothing with it ( or so I see it as ).
What I want to know if there is a way for Caliburn to constrain input to its binding in someway. For example:
I have a TextBox that is bound to a TimeSpan in the VM.
Writing 00:00:10 works fine and sets the TimeSpan to 10 seconds.
If I would write 00:00:-10 nothing happens and the binding remains at the previous value that did properly bind.
Your issue is not related to Caliburn.Micro that simply helps you connect your view to your view-model using data binding. What you need to use is validation of the data binding. You can read more about data binding in Silverlight in particular the Data Validation section is what you should study.
Caliburn.Micro automatically creates bindings using conventions. However, you may have to customize these bindings in XAML to get the desired validation behavior.
In the case where you write 00:00:-10 your validation fails because an exception is thrown from the binding engine's type converter. If the binding expression for the TextBox has a ValidatesOnExceptions property value set to true you will get visual feedback that the value is invalid. And because the entered value couldn't be converted to a TimeSpan no change is made to the view-model.