Click here to Skip to main content
Licence CPOL
First Posted 24 Sep 2008
Views 9,475
Downloads 73
Bookmarked 15 times

An Overlay to Focus on Control

By | 24 Sep 2008 | Article
This should help in improving usability

Introduction 

I was thinking about possibilities to improve usability and one of my ideas was to "focus" on a control to show the user where s/he can do something. 

Using the Code

The usage is pretty simple. After adding a reference to the library, just type some code that looks like this: 

var overlay = new Focuser.FocusOverlay<TextBox>(this.Container, this.Test);
overlay.Show();	 

To hide the overlay on mouseclick, your code should look like this:

overlay.MouseDown += new MouseButtonEventHandler((sender2, e2) =>
    {
        overlay.Hide();
        this.Test = (TextBox)overlay.CloneBack() 
    }); 

The CloneBack function replaces the original control by the one that is shown in the overlay (which is a clone). You need to call this function if you want to keep the changes made to the control while showing it in the overlay.

Important: If you have a variable keeping a reference to the control, which is usually the case if you have given a name to the control, you need to reassign this variable! Otherwise, the reference is out-of-date.

Background

The overlay is an Adorner, which you can read more about here.

To use a control in an Adorner, one has to override several functions from the Adorner class, which are VisualChildrenCount, GetVisualChild, MeasureOverride and ArangeOverride. And - you have to set the child using the AddLogicalChild and AddVisualChild functions.

The child is not the focused control itself, but a Canvas containing the control. This is needed to place the control exactly at its original position. The absolute original position can be found out like this:

var pos = this.FocusedControl.TransformToAncestor(this.Target).Transform(new Point());
 
//Subtract margin because the margin is also cloned 
pos -= new Vector(this.FocusedControlClone.Margin.Left, 
	this.FocusedControlClone.Margin.Top);  

As you can see, the position is found out using the TransformToAncestor function, which returns a GeneralTransforum. Then you have to subtract the margin from the position because it is also cloned.
To find out the width and height of the control, its ActualWidth and ActualHeight property are used.

The position is updated by a timer to stay up-to-date when the window is resized. You can test this in the demo application.

The control to focus on must be a FrameworkElement, because this is the class containing the Parent-property which is needed to replace the original control by the clone.

That only works if the control is contained by a Panel or ItemsControl. The code looks like this:

this.Canvas.Children.Remove(this.FocusedControlClone);
//Exchange control
if (this.FocusedControl.Parent is Panel)
{
    var parent = this.FocusedControl.Parent as Panel;
    parent.Children.Remove(this.FocusedControl);
    parent.Children.Add(this.FocusedControlClone);
}
else
{
    var parent = this.FocusedControl.Parent as ItemsControl;
    var index = parent.Items.IndexOf(this.FocusedControl);
    parent.Items.Remove(this.FocusedControl);
    parent.Items.Insert(index, this.FocusedControlClone);
}

//Update reference to original control
this.FocusedControl = this.FocusedControlClone; 
//Remove reference to clone, because this is the original now 
this.FocusedControlClone = null; 

Points of Interest

The cloning is done in an interesting way that I actually got from the internet:

if (original == null)
    return null;

string s = XamlWriter.Save(original);
StringReader stringReader = new StringReader(s);
XmlReader xmlReader = XmlTextReader.Create(stringReader, new XmlReaderSettings());   

return (T)XamlReader.Load(xmlReader); 

This might not be very elegant, but it works.. ;-).

History

  • 24.09.08: Article created

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

elektrowolf

Other
School
Germany Germany

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 24 Sep 2008
Article Copyright 2008 by elektrowolf
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid