|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Resources;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Automation;
using System.Windows.Media.Effects;
using System.Windows.Controls.Primitives;
namespace WpfTestApp
{
public partial class Window1 : Window
{
private DependencyObject CurrentHelpDO { get; set; }
private Popup CurrentHelpPopup { get; set; }
private bool HelpActive { get; set; }
private MouseEventHandler _helpHandler = null;
private readonly OuterGlowBitmapEffect YellowGlow =
new OuterGlowBitmapEffect() { GlowColor = Colors.Yellow, GlowSize = 10, Noise = 1 };
public Window1()
{
InitializeComponent();
}
private void winMain_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.F1)
{
e.Handled = true;
ToggleHelp();
}
}
private void ToggleHelp()
{
// Turn the current help off
CurrentHelpDO = null;
if (CurrentHelpPopup != null)
{
CurrentHelpPopup.IsOpen = false;
}
// Toggle current state; add/remove mouse handler
HelpActive = !HelpActive;
if (_helpHandler == null)
{
_helpHandler = new MouseEventHandler(winMain_MouseMove);
}
if (HelpActive)
{
winMain.MouseMove += _helpHandler;
}
else
{
winMain.MouseMove -= _helpHandler;
}
// Start recursive toggle at visual root
ToggleHelp(canvMain);
}
private void ToggleHelp(DependencyObject dependObj)
{
// Continue recursive toggle. Using the VisualTreeHelper works nicely.
for (int x = 0; x < VisualTreeHelper.GetChildrenCount(dependObj); x++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependObj, x);
ToggleHelp(child);
}
// BitmapEffect is defined on UIElement so our DependencyObject
// must be a UIElement also
if (dependObj is UIElement)
{
UIElement element = (UIElement)dependObj;
if (HelpActive)
{
string helpText = AutomationProperties.GetHelpText(element);
if (!helpText.IsNothing())
{
// Any effect can be used, I chose a simple yellow highlight
((UIElement)element).BitmapEffect = YellowGlow;
}
}
else if (element.BitmapEffect == YellowGlow)
{
element.BitmapEffect = null;
}
}
}
private void winMain_MouseMove(object sender, MouseEventArgs e)
{
// You can check the HelpActive property if desired, however
// the listener should not be hooked up so this should not be firing
HitTestResult hitTestResult = VisualTreeHelper.HitTest(((Visual)sender), e.GetPosition(this));
if (hitTestResult.VisualHit != null && CurrentHelpDO != hitTestResult.VisualHit)
{
// Walk up the tree in case a parent element has help defined
DependencyObject checkHelpDO = hitTestResult.VisualHit;
string helpText = AutomationProperties.GetHelpText(checkHelpDO);
while (helpText.IsNothing() && checkHelpDO != null && checkHelpDO != canvMain && checkHelpDO != winMain)
{
checkHelpDO = VisualTreeHelper.GetParent(checkHelpDO);
helpText = AutomationProperties.GetHelpText(checkHelpDO);
}
if (helpText.IsNothing() && CurrentHelpPopup != null)
{
CurrentHelpPopup.IsOpen = false;
CurrentHelpDO = null;
}
else if (!helpText.IsNothing() && CurrentHelpDO != checkHelpDO)
{
CurrentHelpDO = checkHelpDO;
// New visual "stack" hit, close old popup, if any
if (CurrentHelpPopup != null)
{
CurrentHelpPopup.IsOpen = false;
}
// Obviously you can make the popup look anyway you want it to look
// with any number of options. I chose a simple tooltip look-and-feel.
CurrentHelpPopup = new Popup()
{
AllowsTransparency = true,
PopupAnimation = PopupAnimation.Scroll,
PlacementTarget = (UIElement)hitTestResult.VisualHit,
IsOpen = true,
Child = new Border()
{
CornerRadius = new CornerRadius(10),
BorderBrush = new SolidColorBrush(Colors.Goldenrod),
BorderThickness = new Thickness(2),
Background = new SolidColorBrush(Colors.LightYellow),
Child = new TextBlock()
{
Margin = new Thickness(10),
Text = helpText.Replace("\\r\\n", "\r\n"),
FontSize = 14,
FontWeight = FontWeights.Normal
}
}
};
CurrentHelpPopup.IsOpen = true;
}
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Expert in C#, .NET, WinUI/WPF, Azure, and SQL Server.
I started working with .NET and C# professionally in 2003 and never looked back. I have been an integral part of a dozen complete software lifecycles, been a driving force behind two successful startups, and have led development teams.