I know something like this has been asked before, but I just can't get it to work. I have a masked textbox like this:
<xctk:MaskedTextBox IncludeLiteralsInValue="False" Mask="000-00-0000"
TextWrapping="Wrap" Text="{Binding SomeInteger, UpdateSourceTrigger=PropertyChanged}"/>
And, you guessed it, I need to bind it to an int property but I keep getting a parsing exception because it seems to be trying to store the dashes as well. No matter what I do, the masked text box is storing the mask as well, and I can clearly see that by changing my property to string.The problem is, I'm working with someone else's code, and I'm not allowed to change the model of the application, not even the data types. Can someone help me?Thanks in advance
EDIT: I never figured out the way to do this, so I created another intermediate property that stores the string and updates the int as necessary, and bound that to the textbox.
Related
Let's say I have a ViewModel with a data type of float and implements INotifyPropertyChanged interface.
private float Amount;
And then in my UI:
<TextBox Text="{x:Bind Amount, Mode=TwoWay}" />
What happens is that when I'm trying to type the character . (period), the text cursor goes back to the start and just appears right after two presses of period. What could be causing this behavior?
I have tested the code when UpdateSourceTrigger=PropertyChanged as mentioned in the comments. The problem is that PropertyChanged causes the binding to update immediately after each keystroke. Because of this the behavior is quite upredicatable when the input does not contain a valid float. I have seen three different behaviors so far. Once only one digit is entered and period right after that, the binding sometimes converts it to a decimal:
But sometimes this did not happen and the control just let me enter 3. without any change. The behavior is seems really random. The key is that the value that is set to the backing property is then reflected in the UI by virtue of PropertyChanged event and data binding, which causes the text to change and cursor to jump.
Simply said, the problem here is the fact that the property is a float while the input accepts any string. The solution to your problem could be to use a string property for the binding, like AmountText and then in the setter verify that the text is actually a valid float, parse it and manually set the Amount property. This way you would preserve the "immediate" updating of the value as soon as a valid input is entered while you would also avoid the weird behavior you are seeing.
Also check out the WinRTXamlToolkit and its NumericUpDown control, which might be a better solution for your goal as it provides a natural way for the user to enter numeric values.
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'm looking for a reason why my code isn't doing its job:
In XAML I use:
<TextBox Text="{Binding Path=Txt_8, Converter={StaticResource DefKonverter}, ConverterParameter='UserAlias'}"/>
In C# there are an IValueConverter which giving me a default value when the ConverterParameter='UserAlias'. For ex. the string 'Jettero'. This works well for that point I see in my TextBox the text 'Jettero'.
I saving my record to database, but in the record Txt_8 still NULL ! (Other fields are saved well)
Looks like the Binding not updating the record field behind the TextBox.
=========== Update start
CONCLUSION: This is not working because the Binding working in one direction. The Converter good for showing special things what makes your user experince better but not to save it.
=========== Update end
A similar issue backward happens also, In XAML:
<TextBox Text="{Binding Path=Date_1, Converter={StaticResource DefKonverter}, ConverterParameter='\{0:yyyy-MM-dd\}TimeStamp'}"/>
This working as it should in the record behind: when I write in the TextBox the '.' character it 'translates' to the today's date. After I save the record, it contains the date.
But in the TextBox I still see the written '.'.
In this sit the Binding not updating the TextBox over the record.
=========== Update start
CONCLUSION: This is not working well because the Binding working in one direction. The Converter good for change the data in that shape how you wanna store.
What is still not answered: when I convert '.' into the present date, it is not showing that - now I see the reason. BUT in the Converter if I'm using a Modal window to somehow extend the data what I wrote in (finding a full text for a keyword), that extended information SHOWS UP in my TextBox beside to store of it.
=========== Update end
I don't know what I miss... I checked lot of using of the default and IValueConverter solutions, but this simple sit never came up. Can anyone help?
I think you might be expecting behaviour from a value converter for which it wasn't designed. What is happening is:
On rendering the textbox, the binding reads a value, let's say null, from your property Txt_8, passes that to the converter, which gives it the value to render, in your example 'Jettero'. This means that the visual representation of your null is Jettero. This isn't meant to (and won't) consequently replace your null with 'Jettero' because, according to the binding engine, it has successfully loaded the value from the source and returned it to the target.
The ConvertBack method of the value converter is supposed to cater for the scenario where the value is changed on the UI and needs to be converted back for storage.
Moral of the story: don't use a value converter for specifying a "default" value for the binding. If your property needs a default value, assign it that in your constructor or initializer. If you want your property value to change itself as it is assigned a value, implement it there, instead of in the converter.
For instance, you can define a Date property like this instead of using a converter:
// disclaimer: untested pseudo-code
private DateTime? _dateTimeField;
public string SomeDateProperty
{
get { return _dateTimeField.ToString('dd-MM-yyyy'); }
set
{
if (value == '.')
value = DateTime.Today.ToString();
_dateTimeField = DateTime.Parse(value);
}
}
I feel like I'm going to reinvent wheel so I would like to know if WPF has bult-in support for what I'm trying to achieve. I'm building an app that will allow people to enter some text in a textbox, and then see it formatted in a textblock.
I would like that the user be able to format the text himself by inputing things such as
This [BusinessSpecificStyle] is [/BusinessSpecificStyle] a sample text
My purpose is to be able to easily change the presentation of all my documents by simply changing the underlaying rules in BusinessSpecificStyle. However I don't know what is the best way to implement that with WPF. I was thinking of using a BBCode parser like this one but supposing I go that way, I don't see how I will be able to convert the resulting XAML into TextBlock children programatically, and I seriously wonder if there isn't some kind of built in support for that.
Thanks for your help
IValueConverter is what you are looking for.
Create the converter and format your text based on the bindings passed from the XAML.
You can get multiple samples over the net for creating IValueConverter. Refer to the link here and here to get you started.
Not sure if you are asking for Converter here. To me it reads that you want to control the style of a block of text depending on some background and common style?
If that is the case, you want to set the inlines of your text block to seperate your text into run elements, which can reference a specific style resource.
<TextBlock>
<TextBlock.Inlines>
<Run>This</Run>
<Run Foreground="{StaticResource BusinessSpecificStyleForeground}">is</Run>
<Run>a sample text</Run>
...
in this case, you create a resource which defines the binding styles for run or bind the Style in it's entirety.
Apologies if I am making up a new question, I see you've marked an answer but wanted to add this just in case.
In a form, I have a TextBox Binding an Object on its member property "Title". Along with it is a "Save" button to test the binding.
Seems like the underlying object property does not get updated unless the textbox loses focus. But there no form.ActiveControl.Blur() for use. Besides, this does not seem like a sound hack.
Anyway to do this better? Thanks.
EDIT: Sorry for not being clear. My question is in the title: "How to commit a TextBox". I use the term "commit" from the DataGridView commit and BindingSource commit. And it's in WinForms. (Have never worked with WPF, so it didn't occur to me. Sorry).
The actual scenario I have is I have a bunch of TextBox binded to property of a single Object. The user enters values in all the TextBox and when the user clicks save (toolbar button), the last TextBox is still in focus (or in editing mode) hence the save will not capture the last value in the last textbox.
I want to find the correct way to "commit" the textbox value just before saving.
Thanks.
Since the question has been updated to indicate this is WinForms, you'll need to handle things a little differently than if this were a WPF application. Fortunately, it turns out that the solution is very simple.
Whenever the user clicks on the "Save" button (so, say, in your Save button's Click event handler), you need to call the EndEdit method on your BindingSource. This will cause all pending changes to be committed to the underlying data source, exactly what you were hoping to accomplish.
Also see the relevant documentation on MSDN for more details.
Sounds like WPF from the problem description..
You want to change the binding so that it updates when the property value changes instead of when the textbox loses focus (which is the default when binding to TextBox.Text). You can do this by setting the UpdateSourceTrigger property on your binding:
<TextBox Text="{Binding UpdateSourceTrigger=PropertyChanged}"/>