2011-08-02 58 views
3

我有兩個相交的矩形。當鼠標懸停在它們上方時,我希望它們的不透明度發生改變。它適用於鼠標懸停在其中一個上面的情況。但是當鼠標位於矩形的相交區域時,只有上面的矩形改變其不透明度。你能否讓我知道在這種情況下如何讓兩個矩形改變不透明度?MouseEvent不起泡

<Window x:Class="WpfTestApp.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfTestApp="clr-namespace:WpfTestApp" Title="MainWindow" Height="350" Width="525" > 
<Window.Resources> 
    <Style x:Key="RectangleHighlighter" TargetType="{x:Type Rectangle}"> 
     <Setter Property="Opacity" Value="0.25" /> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="True"> 
       <Setter Property="Opacity" Value="1" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 

    <Grid x:Name="LayoutRoot"> 
     <Rectangle Stroke="Black" Width="100" Fill="Green" Height="1000" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/> 
     <Rectangle Stroke="Black" Width="1000" Fill="Green" Height="100" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/> 
    </Grid> 
</Window> 

回答

2

其實類似的做法,高科技型魔力描述:

<Window.Resources> 
    <Style x:Key="RectangleHighlighter" TargetType="{x:Type Rectangle}"> 
     <Setter Property="Opacity" Value="0.25" /> 
     <Style.Triggers> 
      <Trigger Property="Tag" Value="MouseOver"> 
       <Setter Property="Opacity" Value="1" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 

<Grid x:Name="LayoutRoot" Background="Transparent" MouseMove="LayoutRoot_MouseMove"> 
    <Rectangle Stroke="Black" Width="100" Fill="Green" Height="1000" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/> 
    <Rectangle Stroke="Black" Width="1000" Fill="Green" Height="100" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/> 
</Grid> 

而且它的代碼隱藏:

private List<DependencyObject> hitResultsList = new List<DependencyObject>(); 

    private void LayoutRoot_MouseMove(object sender, MouseEventArgs e) 
    { 
     // Retrieve the coordinate of the mouse position. 
     Point pt = e.GetPosition((UIElement)sender); 

     // Clear the contents of the list used for hit test results. 
     hitResultsList.Clear(); 

     // Set up a callback to receive the hit test result enumeration. 
     VisualTreeHelper.HitTest(LayoutRoot, null, 
      new HitTestResultCallback(MyHitTestResult), 
      new PointHitTestParameters(pt)); 

     // Unset all children 
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(LayoutRoot); ++i) 
     { 
      var element = VisualTreeHelper.GetChild(LayoutRoot, i) as FrameworkElement; 
      if (element != null) 
      { 
       element.Tag = null; 
      } 
     } 

     // Perform actions on the hit test results list. 
     foreach (var dependencyObject in hitResultsList) 
     { 
      var element = dependencyObject as FrameworkElement; 
      if (element != null) 
      { 
       element.Tag = "MouseOver"; 
      } 
     } 
    } 

    // Return the result of the hit test to the callback. 
    public HitTestResultBehavior MyHitTestResult(HitTestResult result) 
    { 
     // Add the hit test result to the list that will be processed after the enumeration. 
     hitResultsList.Add(result.VisualHit); 

     // Set the behavior to return visuals at all z-order levels. 
     return HitTestResultBehavior.Continue; 
    } 

當然,它能夠更好地添加一些特殊的附加屬性和行爲的這種情況。

+0

感謝Kreol的回覆。正如我在HiTech評論中所提到的那樣,我更傾向於使用僅限xaml的解決方案。如果你可以建議一個xaml唯一的解決方案,它將是偉大的,否則我會嘗試這個。 –

+0

不幸的是,我猜這個任務沒有「xaml-only」解決方案。所以我建議你 - 只是將所有這些代碼分離爲一個容器控件的特殊附加屬性(行爲),當然還要添加一些附加屬性,而不是在我的示例中使用的標記。通過這種方式,您將能夠使用這些來自XAML的附加屬性而無需代碼隱藏。 – Kreol

1

您需要將懸停處理程序添加到父格代替,使這兩個矩形已經IsHitTestVisible =假,並使用VisualTreeHelper.FindElementsInHostCoordinates確定實際上是什麼對象鼠標(1個或多個)下。

如果你必須有它的風格爲基礎,馬里奧Vernari的建議將工作,但懸停將觸發在網格中的任何地方,而不是在矩形。

這給我一個非常有用的附加行爲的想法。該行爲將實現上面概述的代碼,但會觸發子對象上的懸停事件,因此您仍然可以使用樣式來執行該操作......將不得不嘗試一下。

+0

感謝HiTech的回覆。我更傾向於只使用xaml解決方案。你能建議嗎?如果不行的話,我會試試這個。 –

+1

@Souvik Basu:* Xaml-only *表示您需要通過一些新手段來模擬現有活動。我會嘗試創建一個行爲來生成事件(或狀態更改)。 –

0

嘗試將樣式應用於網格元素。

+0

感謝馬里奧的回覆。但是這不會達到我的目的,因爲我希望只有當鼠標懸停在它們上方而不是在網格上方時才突出顯示矩形。 –

+0

網格沒有背景色(即空),所以沒有捕獲所有的鼠標事件。如果您嘗試將網格懸停在矩形上,則不會有任何淡化(無事件)。但是,除非將背景保留爲空,否則「透明」不相同! –

+0

注意:我已經在WPF上試過了,它完美地工作。但是,我沒有嘗試Silverlight。 –