[Silverlight] 透過Grid來初步了解物件的MouseEnter、HitTest機制

  • 5572
  • 0
  • RIA
  • 2013-07-14

這次要跟大家透過Grid來初步認識Silverlight中物件的HitTest機制。

 

讓我們先來看個小範例(請動動你的滑鼠在左右兩邊的白色框框中移動看看):

 

上面的小範例其實就是兩個Grid,當滑鼠移到Grid上面觸發了MouseEnter事件的時候,Grid裡面放的TextBlock透明度會改為100,就這樣而已,但是兩邊跑出來的結果卻大大不相同。

左邊的Grid一定得要把滑鼠動到有文字的範圍,才會觸發MouseEnter事件,而右邊的Grid則是滑鼠移進白色框框就會觸發MouseEnter事件了。

 

我們先來看看裡面的XAML是怎麼寫的~

MainPage.xaml

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:theme="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.ExpressionDark"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
	xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
	x:Class="SL_BackgroundAndHitTest.MainPage"
    mc:Ignorable="d"
    Width="Auto" Height="Auto"
    d:DesignWidth="800" d:DesignHeight="600">
    <theme:ExpressionDarkTheme>
    	<Grid x:Name="LayoutRoot" Background="Transparent">
    		<Grid.ColumnDefinitions>
    			<ColumnDefinition Width="0.5*"/>
    			<ColumnDefinition Width="0.5*"/>
    		</Grid.ColumnDefinitions>
    		<Grid.RowDefinitions>
    			<RowDefinition Height="30"/>
    			<RowDefinition Height="0.933*"/>
    			<RowDefinition Height="0.067*"/>
    		</Grid.RowDefinitions>
    		<TextBlock TextWrapping="Wrap" Text="預設的Grid" FontSize="16" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    		<TextBlock TextWrapping="Wrap" Text="背景色設為透明的Grid" Grid.Column="1" Margin="0" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    		<Border Margin="10" Grid.Row="1" BorderThickness="1" BorderBrush="White">
    			<Grid x:Name="gridNormal">
    				<i:Interaction.Triggers>
    					<i:EventTrigger EventName="MouseEnter">
    						<ei:ChangePropertyAction TargetName="txtMouseEnter1" PropertyName="Opacity" Value="1"/>
    					</i:EventTrigger>
    				</i:Interaction.Triggers>
    				<TextBlock x:Name="txtMouseEnter1" HorizontalAlignment="Center" TextWrapping="Wrap" Text="偵測到MouseEnter事件" VerticalAlignment="Center" 
    				    FontSize="16" Opacity="0"/>
    			</Grid>
    		</Border>
    		<Border Grid.Column="1" Margin="10" Grid.Row="1" BorderBrush="White" BorderThickness="1" >
    			<Grid x:Name="gridColored" Background="Transparent">
    				<i:Interaction.Triggers>
    					<i:EventTrigger EventName="MouseEnter">
    						<ei:ChangePropertyAction TargetName="txtMouseEnter2" PropertyName="Opacity" Value="1"/>
    					</i:EventTrigger>
    				</i:Interaction.Triggers>
    				<TextBlock x:Name="txtMouseEnter2" TextWrapping="Wrap" Text="偵測到MouseEnter事件" HorizontalAlignment="Center" VerticalAlignment="Center" 
    				    FontSize="16" Opacity="0"/>
    			</Grid>
    		</Border>
    		<Button Content="重設" HorizontalAlignment="Center" Margin="0" Grid.Row="2" Width="92" VerticalAlignment="Center">
    			<i:Interaction.Triggers>
    				<i:EventTrigger EventName="Click">
    					<ei:ChangePropertyAction TargetName="txtMouseEnter1" PropertyName="Opacity" Value="0.25"/>
    				</i:EventTrigger>
    			</i:Interaction.Triggers>
    		</Button>
    		<Button Content="重設" HorizontalAlignment="Center" Margin="0" Grid.Row="2" Width="92" VerticalAlignment="Center" Grid.Column="1">
    			<i:Interaction.Triggers>
    				<i:EventTrigger EventName="Click">
    					<ei:ChangePropertyAction TargetName="txtMouseEnter2" PropertyName="Opacity" Value="0.25"/>
    				</i:EventTrigger>
    			</i:Interaction.Triggers>
    		</Button>
    	</Grid>
    </theme:ExpressionDarkTheme>
</UserControl>

 

仔細看上面兩個Grid的內容,其實只有一個地方不一樣,就是背景!!但是執行出來的結果卻是天差地遠~這究竟是為什麼呢?

其實會造成上面的原因,是每個物件的HitTest機制有所不同,而Grid預設的HitTest機制為:得要碰觸到有放置物件或是有被填色(包含透明的背景色)的地方才會觸發(需要更進一步的資訊可以參考Silverlight的HitTest)。

因為Grid預設的背景色是Null(也就是Background="x:Null"),所以就算滑鼠移進去也是不會觸發MouseEnter事件,如果不想花腦力去挑一個背景色,又希望能觸發MouseEnter事件,最簡單的解決之道就是直接將背景色設為Transparent。

但是放在Grid裡面的TextBlock就不一樣了,只要是滑鼠滑過TextBlock的範圍,就算不在文字上面,也會觸發MouseEnter事件(而且Silverlight的TextBlock沒有Background屬性可以改)。

只要善用這個特性,其實就能更輕鬆的作出更豐富的元件(例如常常看到的,當滑鼠滑過某一筆資料,就會在旁邊出現編輯、刪除等等的按鈕)。

小地方,但是有著大大的學問~特別舉出來跟大家分享。

 

最後一樣附上專案原始檔,請自行服用: