WPF C# Textbox text change update in ViewModel - c#

Hello I am working on a simple MVVM project; a simple text/config editor that loads a config file and then it checks in the ViewModel in case the file has been changed, it enables the Save menu item simply by binding a boolean property. But here comes a problem, where I can't find any property in the textbox control that could be bound to a vm property in case a change happens in the text. I have managed to somehow simulate this by creating an event in the code-behind :
(DataContext as AnalizeSectionViewModel).ContentChanged = true;
The event is fired on any text change. But I would like to bind a property from the textbox, something like:
IsModified="{Binding ContentChanged}"
Can such a thing be done?

You should be able to just bind the Text textbox property to your model via binding
Text="{Binding MyViewModelProperty}"
Anytime the text in your textbox changes your property in your model will change which will allow you to do 'stuff' when that occurs. This will fire the property changed event when the user moves to out of the field.
Now, if the intent is for it to fire each time the user types then you can explicitly tack on the
UpdateSourceTrigger="PropertyChanged"
By setting it to PropertyChanged, you will get a notification each and every time the text changes.

Related

How to set the focus on a TextBox in the ViewModel (WPF/MVVM)?

I have a WPF-Application with MVVM and a few TextBoxes.
In my ViewModel I evaluate the input of the textboxes (database query) and decide which TextBox to focus next. If the input is incorrect I want to output a MessageBox and keep the focus on the current TextBox.
My evaluation is triggered by a "LostFocus" event but I have no clue how to set the focus on a specific TextBox in ViewModel.
As the view model should not reference the view, i would approach this via an event. Declare an event on the view model which is raised when the focus should happen. The event args can contain information about which TextBox is supposed to be focused.
You then need to handle the event in the view where you can get a reference to your TextBox. How exactly this happens depends on your exact code and binding mechanism. If you have a view-model-first approach, you can already access the view model in the view constructor and subscribe to the event there.
If you want to avoid code-behind in the view you will have to use markup extensions or attached properties, which i would probably not consider to be worth the effort.

Do i have to implement all usercontrol properties by interface in WPF?

I'm programming a bunch of WPF usercontrols (not CommonControls!) using an Interface for the common properties like the alignments or the Content (depending on the control; TextBox returns the Text, and Label the Content per example).
Now i get to controls like the Checkbox, which have the not so common property IsChecked.
Do i have to implement this property by the Interface or is it allowed to program it in the usercontrol itself?
I hope you're talking about binding a property to a view model or directly mentioning the property value in the xaml itself.
It actually depends upon your requirement. We normally bind a property value to a view model or code behind when that property needs to be checked by certain conditions and then to be set. If you're sure of the property's value, you can set it in xaml itself.
For example if you want to set a textbox's IsEnabled property, and you're sure that the text box is always editable. Then set it as true in xaml itself. But if you're text box need to be enabled during an event is handled, bind it to a property in view model and set it to true during the event trigger.
Okay, i have to guess it was a dumb question.
But after eight hours you don't know anymore, if you're Hillary or Donald.
The answer is: An Interface can inherit from another and implement all members from the "parent" interface.

WPF DataTrigger on PropertyChanged

I have a view model property that is set to runtime objects. I want to trigger an animation whenever this property changes, so I was planning to use DataTrigger. However, DataTrigger obviously has the requirement for a Value property--one that I don't know at design-time.
Is there a built in way to trigger an animation whenever a value changes, regardless of what it changes into?
I saw this question but I was wondering if there was anyway to do it purely in XAML. Otherwise I figure I could probably fire an event from my View Model whenever the property changes and listen to that.
One method would be to create a User Control with a dependency property and then bind both of your other properties to that i.e. one at compile time and the other at runtime. Alternatively you could use an Attached Behaviour to do the same thing.
Can add a boolean property and trigger the animation based on the bool property. Whenever the original property changes, set and reset the boolean property so that it triggers the animation and also goes back to default value for next notification.

C#(Winforms) Databinding using Listbox.SelectedValue as data source (master-detail)

I have a listbox bound to a List<object> as its DataSource. What I'm wanting to do is use the SelectedValue property of the Listbox (i.e the object corresponding to the current selection) as a DataSource for some textboxes that will display certain values of the object for editing.
I've tried
TextBox.DataBindings.Add(new Binding("Text", ListBox, "SelectedValue.name"));
and
TextBox.DataBindings.Add(new Binding("Text", ListBox.SelectedValue, "name"));
but as there is nothing selected in the ListBox (because the form hasn't been shown yet), I get an exception about "Value cannot be null".
Now I know that I can (re)bind to ListBox.SelectedValue in my form's SelectionChangeCommitted handler (that is, after a selection has been made), but if i have to do that I might as well just set the TextBox's value directly (admittedly I could just do this to resolve the issue, but I'd like to learn more about databinding).
So my question is, in short: Is it possible to bind to ListBox.SelectedValue once (initially, before the ListBox has a selection) and avoid the null value exception, and if so, how?
I'm not sure which control your projectNameCtrl is, but you'll want to bind your TextBox. Something like this:
textBox1.DataBindings.Add(new Binding("Text", listBox1, "selectedvalue"));
Where:
textBox1 is your TextBox
listBox1 is your ListView
EDIT
You should be able to data bind a ListBox even if that ListBox has no selected items so your 'value cannot be null' must be for another reason. I suggest using the debugger to determine which object specifically is null.
You can ensure you don't data bind a control more than once by first checking the control's DataBindings.Count property; if it's equal to zero you haven't yet data bound that control:
if (textBox1.DataBindings.Count == 0) {
// OK to data bind textBox1.
}
Off the top of my head, I think you'd need to do something on each selectedItemChanged event...
I know this doesn't answer your question, but I'd look at using WPF instead since this is so much more elegant to do in WPF, and let's face it, by not creating a GUI in code (using XAML instead) your sanity will be much more intact when you finish your project. I don't recall enough windows forms, but in WPF, you just implement INotifyPropertyChanged on your back-end object that you're binding to, and then when you bind to the SelectedItem property of that ListBox, you automatically get updates since the SelectedItem property is a DependencyProperty.

ComboBox SelectedItem vs SelectedValue

The following code works as you’d expect — MyProperty on the model is updated when the user picks a new item in the dropdown.
comboBox1.DataBindings.Add("SelectedValue", myModel, "MyProperty", true,
DataSourceUpdateMode.OnPropertyChanged);
The following, however, doesn’t work the same way and the model update isn’t triggered until the input focus moves to another control on the form:
comboBox1.DataBindings.Add("SelectedItem", myModel, "MyProperty", true,
DataSourceUpdateMode.OnPropertyChanged);
Does anybody know why? I don’t even know where to start investigating the cause. Pointers in the right direction to start the investigation or an outright explanation would be equally appreciated.
Aside: for my purposes, I ended up binding to both SelectedItem and SelectedValue. This way I get instant model updates based on UI changes (through the SelectedValue binding), and UI updates based on programmatic model changes (through the SelectedItem binding).
The ComboBox control inherits from the ListControl control.
The SelectedItem property is a proper member of the ComboBox control. The event that is fired on change is ComboBox.SelectionChangeCommitted
ComboBox.SelectionChangeCommitted
Occurs when the selected item has changed and that change is displayed in the ComboBox.
The SelectedValue property is inherited from the ListControl control.
As such, this property will fire the ListControl.SelectedValueChanged event.
ListControl.SelectedValueChanged
Occurs when the SelectedValue property changes.
That said, they won't fire the INotifyPropertyChanged.PropertyChanged event the same, but they will anyway. The only difference is in the firing event. SelectedValueChanged is fired as soon as a new selection is made from the list part of the ComboBox, and SelectedItemChanged is fired when the item is displayed in the TextBox portion of the ComboBox.
In short, they both represent something in the list part of the ComboBox. So, when binding either property, the result is the same, since the PropertyChanged event is fired in either case. And since they both represent an element from the list, the they are probably treated the same.
Does this help?
EDIT #1
Assuming that the list part of the ComboBox represents a property (as I can't confirm since I didn't write the control), binding either of SelectedItem or SelectedValue affects the same collection inside the control. Then, when this property is changed, the same occurs in the end. The INotifyPropertryPropertyChanged.PropertyChanged event is fired on the same property.
I suspect that the SelectedItem property of the ComboBox does not change until the control has been validated (which occurs when the control loses focus), whereas the SelectedValue property changes whenever the user selects an item.
Here is a reference to the focus events that occur on controls:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validated.aspx
This is a long-standing "feature" of the list controls in .NET in my experience. Personally, I would just bind to the on change of the SelectedValue property and write whatever additional code is necessary to workaround this "feature" (such as having two properties, binding to one for SelectedValue, and then, on the set of that property, updating the value from SelectedItem in your custom code).
Anyway, I hope that helps =D
If you want Selected.Value being worked
you have to do following things:
1. Set DisplayMember
2. Set ValueMember
3. Set DataSource (not use Items.Add, Items.AddRange, DataBinding etc.)
The key point is Set DataSource!
If we want to bind to a dictionary ie
<ComboBox SelectedValue="{Binding Pathology, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{x:Static RnxGlobal:CLocalizedEnums.PathologiesValues}" DisplayMemberPath="Value" SelectedValuePath="Key"
Margin="{StaticResource SmallMarginLeftBottom}"/>
then SelectedItem will not work whilist SelectedValue will

Categories

Resources