Archive
Fix: Hypelinks not clickable in RichTextBox under Silverlight
Just fixed a nasty bug in ClipFlair Studio (http://studio.clipflair.net), where one couldn’t click hyperlinks in the Text component when set at ReadOnly mode. In that mode hyperlinks should open up new web pages (in Edit mode you can edit/remove them only of course), but instead when clicked they would show something like a focus rectangle (which they normally never show).
The situation was hard to debug since it wasn’t obvious what had caused the issue (it was working some time ago). I eventually found out that when the RichTextBox in Silverlight (may occur in WPF and WinRT too, haven’t tried) has a Transparent background, then Hyperlinks in it let MouseLeftButtonDown events pass through, so OnMouseLeftButtonDown will fire at their visual parent (or other visual ancestor) if no component in the visual chain marks the event as handled (such events bubble up towards the top of the visual hierarchy/containment chain).
This shouldn’t be much of a problem, if there wasn’t another issue, where if the ancestor called CaptureMouse in their OnMouseLeftButtonDown overriden method (from Control class), which is usual in mouse dragging code (in my case it was a FloatingWindow [TextWindow] that was the visual ancestor of RichTextBox), the hyperlink fails to fire when clicked and shows that weird solid-line border arround it instead.
The fix was easy once I knew what was happening, I attached a MouseLeftButtonDown event handler to the RichTextBox (if one was subclassing it [assuming it allows to do so] they could also have opted to add an overriden OnMouseLeftButtonDown method) that sets Handled property of the event parameter to true to consume it. The fix is available at CodePlex.
One can verify that the fix works now by downloading a sample ClipFlair Activity from https://www.dropbox.com/s/1zr36190xb0m6vk/Test_Text_URLs.clipflair and opening it in ClipFlair Studio. Can also download and build/run the source code of the previous broken version 1faaa8b35749 and test with that save activity file to see that the URLs didn’t open before when clicked but showed a rectangle arround them intead.
HowTo: Drop files onto Silverlight controls
I was recently adding drop-files support to ClipFlair Studio, so I had to do some research on the related API that is available to Silverlight apps.
Silverlight supports a limited set of Drag-and-Drop interaction with the operating system (supposedly for security reasons, but most probably because of the classic cross-platform implementation pains).
For example it allows you to drop a collections of file objects from the operating system’s file explorer (or other similar application) onto a Silverlight drop target, but not the other way around.
Also, it doesn’t allow dropping other flavors of content, like text, images etc., only collections of file objects.
To allow dropping files onto a Silverlight control you set AllowDrop property to true and handle the Drop and optionally the DragEnter/DragOver/DragLeave events to provide visual feedback during the drop operation (mostly when over the drop target, unless you do Mouse Capturing).
<RichTextBox
x:Name="rtb"
…
AllowDrop="True"
Drop="rtb_Drop"
DragEnter="rtb_DragEnter"
DragOver="rtb_DragOver"
DragLeave="rtb_DragLeave"
/>
#region DragAndDrop
private void rtb_Drop(object sender, System.Windows.DragEventArgs e)
{
VisualStateManager.GoToState(this, "Normal", true);//the Drop event passes in an array of FileInfo objects for the list of files that were selected and drag-dropped onto the RichTextBox.
if (e.Data == null)
return;IDataObject f = e.Data as IDataObject;
if (f != null) //checks if the dropped objects are files
{
object data = f.GetData(DataFormats.FileDrop); //Silverlight only supports FileDrop
FileInfo[] files = data as FileInfo[]; //…GetData returns null if format is not supportede.Handled = true;
if (files != null)
//Walk through the list of FileInfo objects of the selected and drag-dropped files and parse the .txt and .docx files
//and insert their content in the RichTextBox.
foreach (FileInfo file in files)
Load(file, false);
}}
private void rtb_DragEnter(object sender, System.Windows.DragEventArgs e)
{
VisualStateManager.GoToState(this, "DragOver", true);
e.Handled = true;
}
private void rtb_DragOver(object sender, System.Windows.DragEventArgs e)
{
e.Handled = true;
//NOP
}private void rtb_DragLeave(object sender, System.Windows.DragEventArgs e)
{
VisualStateManager.GoToState(this, "Normal", true);
e.Handled = true;
}#endregion
For the visual feedback you can use VisualStateManager and respective VisualStates at say a Grid that wraps the drop target in the XAML layout.
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DragStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3">
<VisualTransition.GeneratedEasingFunction>
<CircleEase EasingMode="EaseIn"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="DragOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" Storyboard.TargetName="rtb">
<EasingColorKeyFrame KeyTime="0" Value="#FFFFF7D1"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Note that on MacOS-X Safari doesn’t pass drop events automatically to plugins and you have to catch them via Javascript and pass them to Silverlight, plus I’ve read that in MacOS-X Firefox doesn’t support this at all.
Even worse, Microsoft’s workaround article has a typo in the Javascript (should call dragDrop instead of drop) and there is a chance it doesn’t work in latest version of Safari. For more see:
http://msdn.microsoft.com/en-us/library/ee670998%28v=vs.95%29.aspx
http://www.telerik.com/forums/dropping-files-using-safari-on-mac (this says one can use HTML5 events and the Silverlight HTML/Javascript Bridge to notify Silverlight)
http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/
fix: Microsoft mouse right-click failure
The other day my Microsoft Wireless Laser Mouse 6000 (was either a gift from Microsoft Hellas or had ordered it myself from Microsoft Company Store with the credit Microsoft used to give pro-crisis to MVPs) started behaving erratically, failing most of the times to right-click and sometimes doing left clicks instead with some delay, or doing other actions like Paste etc.
It seems the issue was with Microsoft Mouse and Keyboard center software that Windows Update installs. Uninstalling it (from the Windows Control Panel) fixed the issue immediately.
That software is a total failure since it doesn’t support correctly various Microsoft hardware device older models. It shouldn’t install at all in the first place if it finds an incompatible device or try to behave better. It’s a shame that software is from Microsoft itself.
Even worse it that at their webpage they say:
Tell us what you think!
We are interested in your experiences with Microsoft Mouse and Keyboard Center and your Microsoft device!
- Send your comments and questions by clicking on the Send Feedback icon on the Windows 8 desktop, select Apps then Microsoft Mouse and Keyboard Center from the options listed.
Not very helpful for those wanting to send feedback from Windows 7, is it?