If you create a simple button and then choose Edit Template -> Edit a Copy, Blend will automatically generate a style area, along with all the button states (MouseEnter, MouseLeave, Pressed, etc). Nowhere in the generated code does it say that on a "MouseOver" event, change the state to "MouseOver", but it still manages to work!
How does a standard button do it? Is there some sort of AutoEventWireUp going on?
Controls themselves define the states they respect. Unfortunately, there's no magic auto-wiring going on. The Button contains code that determines when the mouse is over it and, in that case, to set it's visual state to MouseOver. The TemplateVisualStateAttribute is what lets Blend know that there is a valid state of a certain on this control, but the code in the control itself is what actually determines what state it is in.
If you are developing your own control, this puts the burden of defining which states your control supports on you, as well as the job of correctly determining which state you are in.
FYI: Most of the built in controls have a list of their supported states in the MSDN documentation. For example, Button for Silverlight 3 is here.
Related
We have a WinForms control (inherits Systems.Windows.Forms.Control) with a custom designer attached to it (inherits ControlDesigner). We need to process some mouse events like clicks in a special area inside our control at design time. To indicate that mouse click is available in that area, we need to change the default 4-arrow cursor to something else - at least, to the standard arrow, but we could not find a way to do that.
We redefined the ControlDesigner.GetHitTest method to return true for that special click rectangle, but the cursor simply flashes when it is over the area. It is changed to the default arrow for some milliseconds, and then back to the 4-arrow cursor which implies the whole control can be selected and moved on the form. Overriding ControlDesigner.OnSetCursor does not have any effect as it seems this virtual method is called only when the cursor is changed to the default 4-arrow cursor. Games with WndProc (trying to intercept WM_MOUSE* events) did not get us any positive results too.
Even when we try to implement samples from related books (like the SimpleLineControl from Eric White's "GDI+ Programming-Creating Custom Controls Using C#"), we have the same behavior.
Our dev env is VS2010/.NET 4.0 which is the minimal requirement. How to make it work in this and later environments?
I have a custom list control derived from Control class.
I need to make it accessible to people with disabilities through MSAA (Microsoft Active Accessibility).
So far I understand that I need to create class that inherits from ControlAccessibleObject and then return its instance in Control.CreateAccessibilityInstance method override.
The problem is that I have implemented this and it seems not work with Windows Narrator tool.
For example, when I click on an item in standard ListView, the Narrator speaks out the selected item text.
But when I click on item in my control, nothing happens (although the item text is requested in my ControlAccessibleObject implementation)
I thought I need to implement IAccessible as well, but I looked on .NET refrence source code and the ListView does not implement this interface. I thought maybe this is implemented in the wrapped Win32 control, so I took a look on similar control - DataGridView - but this does not implement IAccessible as well.
DataGridView have accessibility support, but although I copied all the important code of DataGridViewAccessibleObject, it still does not work in my control.
Do anyone have more experience with custom control accessibility in WinForms?
Okay, I found it: The Control.AccessibilityNotifyClients method does the magic. One have to override this method in a derived control.
However, to make screen readers speak the text, I had to call:
AccessibilityNotifyClients(AccessibleEvents.Focus, index);
AccessibilityNotifyClients(AccessibleEvents.Selection, index);
Here the index is an index of newly selected item.
I found this code in the .NET reference source of CheckedListBox. When I used Focus or Selection event solely, the screen reader have not reacted. The spoken text also depend on the AccessibleObject state that corresponds to a newly selected item.
I'm trying to build a maintenance form in WPF, using Telerik's WPF controls. The idea is to have a grid and a form that are bound to the same collection. Changes to the grid should be immediately reflected in the form, and vice versa. An online example using Telerik's Silverlight controls is here.
My specific problem is that when I enter a new record (by clicking on the "Add" icon in the upper-right of the DataForm), the record is added to both the grid and to the form's collection, but it seems to break the synchronization. The new row in the grid stays highlighted, like the grid thinks it's not done being edited, and while changes to the current record in the form are reflected in the grid, changes to the current record in the grid are no longer being reflected in the form.
But my real problem is more general than that. WPF controls, like Telerik's, are heavily dependent on binding, and in having what they bind to support specific behaviors. In this case, the underlying record needs to support INotifyIEditableObject, so that when the user hits the Cancel button on the form, the EditCancel method on the record can be called. Which is then responsible for setting its properties back to what they had been, and then raising a NotifyPropertyChanged event, so that controls that are informed that they have been so set.
When I didn't have EditCancel working right, I would hit cancel on the form and the values in the grid would not be changed. My guess as to what is going on with the inserts is that something in either my collection or by records doesn't support whatever it is that makes this work. The grid doesn't know that the form has finished editing the record because either my record or the collection hasn't told it.
And here's the real question: how can I find out what these third-party controls are expecting? Telerik's RadGrid can be bound to pretty much anything that can be IEnumerated. But all this neat enhanced functionality depends upon being bound to collections that are very much more specific. I don't get errors, when I bind to a collection that lacks facilities that are needed for certain functions to work, I just get a control that doesn't work.
How can I tell, when working with someone else's control, for which I do not have source code, what functionality it requires, in the objects it binds to?
Your best bet would be to browse Telerik's documentation or ask on their support forums
If that doesn't work, I like to use Snoop for debugging WPF's Visual Tree and Reflector for looking through compiled libraries
I have a following requirement for a very complex UI. (Complex here means there are lot of controls in the form [approximately 100]). I am using MVVM (if my problem requires it to slightly go away from MVVM I am ok with it)
My question is for Editable ComboBox and TextBox. But I would say I like to hear a common algorithm which will fit all controls.
Requirement 1 : The user edits the content and goes to next control, the color of the control/text should become red.
Requirement 2 : When the user comes back to the previously edited control and enters the value which was initially present, the color of the control/text should become back to black.
I know the requirement is tough and I have been breaking my head to design a generic algorithm using which I can store the previous value and call a function to change the color of control.
To just give you all an idea, --> I tried storing 2 properties for every TextBox like Default_Text and Text. But since the number of properties are huge, the memory footprint is very huge. Also maintaining so many properties is very tough.
--> I tried adding a Dictionary to every ViewModel to store what values have got changed. But here the problem I faced was giving unique keys to all the controls in my application, which is not very helpful
--> I had even thought and tried about subclassing controls like TextBox, ComboBox and overriding some methods to suit my requirement, but sadly I failed miserabley when I started adding validations and all.
So here I am stuck with designing a generic WPF property system/algorithm to handle all undo redo functionality, changing styles of controls,etc!!!
It will be really great if you experts can guide me in right direction and also help me in developing such an algorithm/system. A sample illustration will be nice though!!!
I found an answer to the above problem. I used attached behavior for this. More details on this link Function call from XAML from StackOverFlow.
When I databind, I store the initial value of the DataBound variable in the Tag property by using Binding=OneWay. Then I have written a attached behaviour for LostFocus event. Whenever the user enters a control and then goes to other control, it fires LostFocus event and calls my attached behaviour. In this, I check whether the value is equal to the value in Tag. If it is same, I display in black else I display in red.
Attached Behaviour rocks in WPF. I can achieve anything from that cleanly without code cluttering!!!!
Another alternative is to use some "dirty" tracking in your models (or viewmodels) and bind to a properties isdirty (and convert it to a color).
I have a windows forms application with controls like textbox, combobox, datagridview etc.
These controls allow a user to use the clipboad, i.e. cut/copy and paste text. It is also possible to delete text (which is not related to the clipboard).
My application has a menubar with an Edit item containing Cut/Copy/Paste/Delete items, and a toolbar with these items as well. How can I enable/disable these items properly depending in the state of the control having the focus?
I am looking for a generic way, i.e. I look for an implementation I do once, and can reuse for the future independent of the controls my application will use.
There is no generic interface or set of methods for getting cut/copy/paste information from a windows forms control.
I suggest your best approach would be to create a wrapper class for each type of control. Then when you want to update the menu state you get the current control with focus and create the appropriate wrapper for it. Then you ask that wrapper for the state information you need. That way you only need to create a wrapper implementation for each type of control you use. Bit of a pain to start with but other time you only need to add the new controls you come across.
Clipboard information is much easier as you can ask the Clipboard singleton if it has data inside and what type it is. Then again you still need to ask the target control if it can accept that type of information so there is still extra work needs doing.
Create an array for each enable/disable group. Add the controls to the array (of course it has to be of the correct type such as Object or Any, etc. depends on the programming language you are using).
Then to enable, disable just loop through the array and invoke the enable/disable method or function for each control. Again, depending on the language you may need to cast back.