2011-04-13 51 views
15

我有一個BorderCornerRadius屬性設置爲10.在那Border,有一個StackPanel。該面板分別包含兩個帶有藍色和紅色背景的Border如何使邊界修剪子元素?

藍色邊框的左上角和右上角以及紅色邊框的左下角和右下角都伸出第一個邊框的曲線邊緣。我希望將藍色和紅色邊框修剪到父邊框。那可能嗎?順便說一下,我知道如果我爲藍色和紅色邊框的CornerRadius屬性設置相同的值,它將遵循第一個曲線。我不想那樣 - 我想修剪。謝謝!

<Border 
    Width="200" 
    Height="200" 
    BorderThickness="1" 
    BorderBrush="Black" 
    CornerRadius="10"> 
    <StackPanel> 
     <Border Height="100" Background="Blue" /> 
     <Border Height="100" Background="Red" /> 
    </StackPanel> 
</Border> 
+0

你能發表一些說明問題的代碼嗎? – 2011-04-13 13:19:06

回答

18

你可以寫的剪輯屬性的轉換器。例如,轉換器應實現IMultiValueConverter並綁定到實際大小和角半徑。

public class BorderClipConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (values.Length == 3 && values[0] is double && values[1] is double && values[2] is CornerRadius) 
     { 
      var width = (double)values[0]; 
      var height = (double)values[1]; 

      if (width < Double.Epsilon || height < Double.Epsilon) 
      { 
       return Geometry.Empty; 
      } 

      var radius = (CornerRadius)values[2]; 

      // Actually we need more complex geometry, when CornerRadius has different values. 
      // But let me not to take this into account, and simplify example for a common value. 
      var clip = new RectangleGeometry(new Rect(0, 0, width, height), radius.TopLeft, radius.TopLeft); 
      clip.Freeze(); 

      return clip; 
     } 

     return DependencyProperty.UnsetValue; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

用法:

<Border CornerRadius="10"> 
    <Border.Clip> 
     <MultiBinding Converter="{StaticResource BorderClipConverter}"> 
      <Binding Path="ActualWidth" 
         RelativeSource="{RelativeSource Self}"/> 
      <Binding Path="ActualHeight" 
         RelativeSource="{RelativeSource Self}"/> 
      <Binding Path="CornerRadius" 
         RelativeSource="{RelativeSource Self}"/> 
     </MultiBinding> 
    </Border.Clip> 
</Border> 
+0

我已經能夠找到的最好的例子! – 2013-12-18 12:37:47

+0

我曾想過這樣做,但想知道是否有一種XAML信條的方式。 我會試試這個。 我對此事的質疑: http:// stackoverflow。com/questions/24158147/wpf-clipping-a-border – 2014-06-11 09:34:02

+0

這可以用一個正常的轉換器(即不是一個多值轉換器)然後綁定到它自己來完成。這將使綁定更漂亮(即更容易重複使用),並推動把寬度/高度/半徑抓進轉換器的邏輯。 – claudekennilol 2016-06-03 16:06:12

1

ClipToBounds是可能有助於在這種情況下的財產。

編輯:經過一些測試,我注意到,ClipToBounds只關心實際的邊界(即矩形區域的控制應用),所以還是內容在角落伸出...

這似乎暗示簡單的裁剪到邊界是不可能的。您可以將Clip屬性設置爲圓角矩形,但這並不是很方便,因爲我認爲它的大小不能被綁定。

您的選項似乎可以用一個OpacityMask連同VisualBrush或重建時的相關性通過使用MultiBinding & MultiValueConverter改變剪裁...

+0

我恐怕在這裏無法使用Clip to Bounds。 – Boris 2011-04-13 13:44:03

+0

告訴我一些我不知道的... – 2011-04-13 13:44:55

+0

OpacticyMask只有幾何類型,所以你仍然需要一些轉換器,就像@MaratKhasanov的問題 – 2014-06-11 09:35:08

6

還有使用OpacityMask財產僅XAML的解決您的問題。訣竅是在外邊框內創建一個Grid,並將網格的OpacityMask設置爲充當剪貼蒙版的另一個元素。

<Border Width="200" Height="200" 
     BorderThickness="1" BorderBrush="Black" 
     CornerRadius="10"> 
    <Grid> 
     <Grid.OpacityMask> 
      <VisualBrush Visual="{Binding ElementName=clipMask}" Stretch="None" /> 
     </Grid.OpacityMask> 
     <Border x:Name="clipMask" Background="White" CornerRadius="10" /> 
     <StackPanel Background="White"> 
      <Border Height="100" Background="Blue" /> 
      <Border Height="100" Background="Red" /> 
     </StackPanel> 
    </Grid> 
</Border> 

在片段上方我用Border作爲限幅掩模,但它也可以是另一種元素,只要它的填充顏色是不透明的。還要注意,clipMask邊框也具有相同的CornerRadius

受啓發︰http://www.codeproject.com/Articles/225076/Creating-Inner-Shadows-for-WPF-and-Silverlight