I have an application that declares textboxes in various places, like in styles and datatemplates, and now I'm in a situation where I need to change every textbox's standard behavior for getting and losing focus.
What's a good way to do this?
I was thinking of two solutions: one is to derive a new class from TextBox, which I understand is generally frowned upon. The other is to create some kind of style that uses EventSetters, but since the styles and datatemplates in my application don't have codebehind files I donno how an event will find the appropriate event handler.
You can create a style that applies to all TextBoxes using the Key property as follows:
<Style x:Key={x:Type TextBox}>
...
</Style>
You can then modify the Template property of the TextBox and use Triggers to add special behavior to the OnGotFocus and OnLostFocus events.
Based on your feedback, I'd recommend an attached behavior used as follows:
<TextBox b:TextBox.SuppressOnFocus="True"/>
The attached behavior implementation would simply attach to GotFocus and LostFocus and clear/reapply the binding as appropriate.
Under normal circumstances, I, too, would frown upon subclassing TextBox. In this case, since you are changing the behavior of the TextBox, a subclass may be your best option.
If you are going to use this functionality in only one project then you can create UserControls which has a TextBox and access the the OnFocus properties. You can also make a Custom WPF Control which derives from a TextBox and then implement the LocusFocus event.
I have used the same approach to create a User Control TextBox which performs validation:
http://www.highoncoding.com/Articles/578_Creating_WPF_TextBox_UserControl_to_Perform_Custom_Validation.aspx
Related
In Flex (AS3) you can do neat things where you bind a property to an expression/variable/object. e.g. button.enabled = {!obj.name.empty} It makes for very neat GUI validation amongst other things.
I don't see any such facility in Visual Studio GUI designer but wondered if this sort of functionality exists in .Net/C# and if so, to what extent?
I don't see any such facility in Visual Studio GUI designer
In fact there is. Select the form/control in the designer, then go to Properties window and expand the (DataBindings) category. You'll see a couple properties there, and more if you click the (Advanced) item.
to what extent?
It could only bind to a property (no expressions are supported). To make it work, the object providing the property must support property change notification. The standard way is implementing INotifyPropertyChanged interface, but there are also other mechanisms - IBindingListimplementation providing ListChanged event, object providing event named PropertyNameChanged for a PropertyName etc.
As I mentioned, standartly you can bind only to properties. However, at runtime with some helpers you can really bind to a method or expression. I've already provided examples of doing that in the following threads Button enable and disable on text changed event, Exchange UserControls on a Form with data-binding, Custom WinForms data binding with converter not working on nullable type (double?), .Net WinForms design to sync Data and Controls for a single item data binding, and my own question Cross tabular data binding in WPF for more complex scenarios.
Contrary to what some WPF-ers say, there are no WF limits when binding to a custom objects/collections. The only limits are when binding to other control properties because control property notification pattern is not strictly followed like in WPF where it is by design.
How to change the color of text, when a control is disabled.I want to set different color when control is disabled in c# winforms.
Edit: I had made the same mistake as Cody in the comments so corrected my answer.
It depends on which control it is.
For example, if it's a TextBox maybe you could make it ReadOnly instead of disabled. And for some other controls you might be able to do similar things to make them appear disabled without actually being disabled.
However, if you want to do it properly you need to make them Owner-draw or override the OnPaint event and draw the text yourself.
You can just do it manually -- when you disable the control, just change the text colour too?
If you have many controls, you can do this:
attach your form OnChildAdded event
in the event, use if ... is of type structure to determine control type
depending on the control type, register proper OnEnabledChange event
in the event, change text color appropriately
That way, you will have a piece of code that will work for all your forms and will gradually expand to use all the controls you need.
I'll provide some code if that's the way you want to go...
In my project I have a settings form. Where if any changes happen I have to notify user about it if he wants to leave that page without saving his changes. At this time I am doing this by catching every control change event. I am sure there is a better way - like catching the change event from its container. Is it possible?
Rather than worrying about the controls directly, how about creating a Settings class that implements interfaces from System.ComponentModel like INotifyPropertyChanged and IDataErrorInfo and use data binding to get the values in and out of the controls.
Your Settings class can then not only record whether anything has changed but also make validation of the user input easier.
A good place to start is MSDN.
You have the right solution, but you may want to be very generic about catching the change events. For example, you could try something like this right after the InitializeComponent(); line in the constructor:
foreach(Control c in Controls) {
c.TextChanged += new EventHandler(genericTextBox_TextChanged);
}
genericTextBox_TextChanged would set a form-wide hasChanged flag to true, or something really basic like that. You may need to make this into a recursive function that loops through all of the children of c if it has child controls.
Let me offer you some kind of a workaround. My offer is to create a custom DataSet. Then add tables corresponding to the form controls. After this you can bind each form control to this dataset.Pros: You keep all the controls data-bound. So you don't need to care about the changing of particular control. You have just to control dataset changes. Cons (maybe): after this you should rewrite settings preview mechanism. Instead of changing controls you have to change data. IMO, it's not so hard, but I have no idea about this approach in your applicationI think this approach will be, at least, easy to debug.
If it's web, look at the unload event for javascript
I have a custom control and I would like it to act like a button i.e. when you hover over it changes a little so it seems "clickable" to the user
I actually acheived this using the MouseEnter and MouseLeave events and changing the gradient but...
is there a way to apply a style to the user control and say something like TargetType="button" so that it "acts" like a button automatically?
I feel the way i'm doing it is not the best way
As sniper says, you can set a Controltemplate for each state.
Alternatively, you can completely replace a control's visual tree with anything you want - while still keeping the control behavior intact. Check out this post by ScottGu on the topic
In Expression Blend 3, you can edit the different states (Normal, Hover, pressed, selected etc), of any control how you need it. just select your control and click Edit copy template
Add border object and sets its visibility on mousehover and leave event on the control (This will look like a flat\popup button). Additionally set the control's cursor to hand.
You can derive your control from ButtonBase, just like Button, HyperlinkButton, Checkbox, etc.
Sounds a simple question but haven't found a way to do, so would solicit any responses I get.
I have a winform which in turn contains a user control object. based on some condition in the user control, i have to set a value in the winform.
One way could be to pass the winform object as parameter to user control but that would give cyclic dependency. Is there a easy way out?
You can always use events from the user control to the form.
User Control Events in VB and C#
Writing C# Custom Events
Usually I would expose an appropriate event from the usercontrol. The form can subscribe to the event and react accordingly.