众所周知,Silverlight默认并不支持右键点击和滚轮操作。微软曾经在它的DeepZoom解决方案中给出了一套对于滚轮操作的支持方案(包括一个Helper类,其实中含有NestedType,还有一个EventArgs类),但是至今仍然没有比较正式的对于右键的支持,所以我依照微软的思路,做了对于右键支持的通用类,希望能够对大家有所帮助。今天要介绍的,是这个通用方法的全局侦测的版本,即无论用户点击Application内的哪个元素,都全触发事件,至于是否处理,则交给程序员判断。还有一个为特定UI元素监视右键点击的模式,我会在下一篇中介绍。无疑下一个版本将更加面向对象,但是我认为这个版本也是有一定价值的。
首先,在HostPage中设置Silverlight对象的WindowLess属性为true,在asp.net中:
在Html中:
这样,余下的工作就可以通过Silverlight中ManagedCode同Javascript的操作来实现了。在这里,首先提出一个类,它能帮助我们计算出任何一个UIElement从Application的RootVisual的平移值。这个类我写成了静态类,并且写成Extension Method,其实用普通的静态类,同样也是可行的。
public sealed class MouseRightClickEventArgs : EventArgs2
{3
internal MouseRightClickEventArgs(double x, double y)4
{5
m_XOffset = x;6
m_YOffset = y;7
}8

9
private double m_XOffset;10
private double m_YOffset;11

12
public Point GetPosition(UIElement relativeTo)13
{14
if (relativeTo != null)15
{16
Point p = relativeTo.TransformFromRootVisual();17
return new Point(m_XOffset - p.X, m_YOffset - p.Y);18
}19
return new Point(m_XOffset, m_YOffset);20
}21

22
public IEnumerable<UIElement> FindElementsInHitPoint()23
{24
return VisualTreeHelper.FindElementsInHostCoordinates(GetPosition(null), Application.Current.RootVisual);25
}26

27
public bool HitTest(UIElement relativeTo)28
{29
foreach (UIElement element in FindElementsInHitPoint())30
{31
if (element == relativeTo)32
return true;33
}34
return false;35
}36

37
private bool m_Handled;38
// Summary:39
// If you don't want to see the Silverlight Configuration,40
// set it as true41
public bool Handled42
{43
get { return this.m_Handled; }44
set { this.m_Handled = value; }45
}46
}
public sealed class RightClickHelper:IDisposable2
{3
public event EventHandler<MouseRightClickEventArgs> RightClick;4
public RightClickHelper()5
{6
//if (!(Application.Current.Host.Settings.Windowless && HtmlPage.IsEnabled))7
//throw new NotSupportedException("Must set the Windowless of the plug-in as true");8
HtmlPage.Document.AttachEvent("oncontextmenu", this.OnContextMenu);9
}10

11
private void OnContextMenu(object sender, HtmlEventArgs e)12
{13
if (RightClick != null)14
{15
MouseRightClickEventArgs evtArgs = new MouseRightClickEventArgs(e.OffsetX, e.OffsetY);16
RightClick(this, evtArgs);17
if (evtArgs.Handled)18
e.PreventDefault();19
}20
}21

22
IDisposable Members28
}这样,创建一个RightClickHelper的对象,它将侦测全局的右键点击事件,然后将它们提交给程序员,程序员可调用RightClickEventArgs中的方法进行命中测试,并且判断这次点击是否受理。上面提到的为特点的UI元素加入右键点击的帮助类,只是将EventArgs中的相应方法封装进去,在类内部做出判断后再提交给程序员。这种更加面向对象的方式,我将会在下一篇文章中给出。
缥缈落花街 月圆月缺 望峦山平川 雁返君未还 怆然晚春残 忆天上人间

浙公网安备 33010602011771号