How to change C# TextBox behavior, en masse? - c#

Our application has many TextBoxes that we disable at appropriate times. (We set the IsEnabled property to false). Our customer now wants the content of the TextBoxes to be non-changeable, but able to be copied. We can do this by setting IsReadOnly to true and IsEnabled to true.
I don't really want to go to every place in the application where text boxes change state and twiddle with those settings. How can I localize changes, such that I don't need to make a large number of edits? Basically, I want to do something that would be almost equivalent of redefining the set part of IsEnabled, when the value to be set is false. (BTW, our customer would also like us to do some other related changes, such as setting the background color of the text box to a non-default color when "disabling" the text box.)

One way to do this would be to create a subclass of TextBox that allowed you to make these type of changes. However that requires that you change your application to replace all occurrences of <TextBox ... with your control:
<myControl:MyTextBox....
which doesn't really solve your problem of not wanting to change all the code.
However, it would enable you to do the other changes you mention - changing the background colour, etc. a bit easier (though that can be also achieved by overriding the default style in XAML).

I dont really understand your question but I think it would be easiest to create a Background Worker that checks with if ( MyTextBox.Enabled == false ) if the textbox is enabled/disabled.

Related

How do i conditionally format rows in property grid

I am trying to format a property grid, working few years on wpf has rusted my winforms knowledge.
I want to make property name text bold in some cases, I want to use a bool return value from a method, and decide if property name is to be displayed as bold.
Any ideas on how to achieve this, what property what event!?
Back in the day...
Really, this is going way back. I don't remember that there was a way to control the property name appearance directly. You could make sure your property descriptors had categories and those categories would be bold.
Also (and I don't think this is still true in "later" versions of Windows), you could return true from your property descriptor's ShouldSerializeValue method...and it would cause the PropertyGrid to display the property value in bold.
Also seems like you could identify one of your properties as the object's default property (in the object's type descriptor). Seems like there were differing behaviors depending on the version of Windows...after XP, I think this would float the property to the top...but maybe XP and before it would make the property name bold...but I could be misremembering. I've slept more than once since then.
With the property grid, I seem to remember running into the argument that doing any more formatting might interfere with all the complex layout the grid was already doing on the object's behalf. Back then, I was using the property grid to format hierarchical objects...and I remember being impressed with it's capabilities despite it's relative lack of formatting control.
Of course, after spending time in WPF, you can't help but feel like you can affect anything and everything, yes?

MultiDataTrigger Not firing once the button isEnabled property is changed from code behind

I have a button which is enabled/disabled based on validation.hasError property of few textboxes and it works fine, untill i wanna disable and enable this same button from code behind based on some business logic. for example.
if(recordExist) { btn.IsEnabled=true;} else{ btn.isenabled=false;}
now what happens is that once the else logic is carried out and the button is disabled, the button is not re-enabled again even if the validation.HasError of all the controls return false. and like wise if the if logic is carried out and button is enabled it stays enabled even if the validation.hasError returns true. what i want is to somehow re-Trigger the multiDataTriggers to check the Validation.hasError on the textboxes and update the isEnabled property of the button accordingly. i hope i am clear enough.
See Dependency Property Value Precedence on MSDN.
Once you set local value, triggers can't override it. You need to adjust bindings, triggers etc. to take the logic in the code behind into account. If you're using MVVM (and you should), you can add the condition to your view-model.
Alternatively, if you want the control to forget about the local value and let the trigger take precedence, you can use ClearValue. Or you can use SetCurrentValue and avoid giving precedence to the new value. However, you should avoid using these functions, they will make your code harder to understand and maintain.

How can I change (i.e. toggle) the bound, StringFormat property of a WPF control?

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!).

TwoWay binding is not really Two Way?

I have a two way binding on a string dependency property to the Text of a TextBox.
The binding looks like this:
Text="{Binding MyValue, Mode=TwoWay}"
I have some code that fires in OnKeyUp (in an attached property) that sets MyValue. But rather than taking my value and applying it to the Text property, it is going the other way around.
Here are the sequence of events:
The user enters a string of text that looks like this: 0299900650
The user presses enter.
In my on key up I set MyValue to 2999 and move to the focus to the next field.
The setter for MyValue fires and does a NotifiyPropertyChanged with 2999
The LostFocus fires.
The setter for MyValue fires and does a NotifiyPropertyChanged with 0299900650.
It seems to me that my value is not making it back to "TextBox.Text" somehow. When I loose focus the TextBox is updating the value of the string with what it has in the Text property (the unchanged value because my change did not get back.)
Is there some WPF magic I am not aware of here?
NOTE: I have double checked my bindings. (Besides they work from the UI so I imagine they are correct going to the UI.)
NOTE II: When I say the "user enters a string", it is really a scanned barcode. But since I am using a keyboard wedge, it is as if it was typed in. (However, the whole point of setting the value is because I am doing something different if the user scans as apposed to typing.)
UPDATE: I found this was due to another property having a side effect. I was able to fix the problem.
You simply jump into the concurency conflict on WPF binding messaging.
To prove that, do the following:
remove your OnKeyUp even handler
and do the same you did. On Enter click binding mechanism fires and sets your code behind property.
In case when you make on KeyUp, you new value 2999 is surpressed by the binding after.
To manage this correctly make use of Converter and get rid of OnKeyDown even subscription.
I found this was due to another property having a side effect. I was able to fix the problem by fixing that side effect.

Controlling XAML tags from C# code

I have a WPF application , and I would like to modify the background color of the UI based on the user's selection at run time .
Now , I want to create a button that changes the color each time its clicked , so this button must change a value from the XAML tags
Please , help me doing it , I need it badly
Thanks
To make a control red from code:
yourControl.Background = Brushes.Red;
Thomas has given one example of what you could do.
Another option would be to bind the background colour to some property of your data context (probably the ViewModel if you're using MVVM) and make the button click change that property - possibly indirectly via commanding.
They're just different approaches - directly setting the background colour is certainly simpler than going via binding, but it may be less easily testable.
Another option would be to bind the background colour to a property in your DataContext, and update only the property's value when you click the button. This way, you also get to keep your logic and display responsibilities separate.
To say it simply. There is no difference between XAML and C#. In the end it both produces same executable code.
To change property on GUI you should either name your control through x:Name property and then set your property in the backend code file. Or you can DataBind your property to some backing field, preferably by using MVVM pattern.
But you should first understant how WPF works (ESPECIALY DataBinding) before moving to more advanced topics like MVVM.

Categories