/ / ¿Cómo hacer que el borde recorte los elementos secundarios? - wpf

¿Cómo hacer que el borde recorte los elementos secundarios? - wpf

tengo un Border con CornerRadius propiedad establecida en 10. Dentro de ese Border, hay una StackPanel. El panel contiene dos Borders con fondos azules y rojos, respectivamente.

Las esquinas superior izquierda y superior derecha de lael borde azul y las esquinas inferior izquierda y derecha del borde rojo sobresalen de los bordes curvos del primer borde. Deseo hacer que los bordes azul y rojo se ajusten al borde principal. ¿Es eso posible?

Por cierto, sí sé que si establezco el mismo valor para CornerRadius Propiedad de los bordes azul y rojo, seguirá la curva del primero. No quiero eso, quiero recortar. ¡Gracias!

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

Respuestas

19 para la respuesta № 1

Puedes escribir un convertidor para la propiedad Clip. El convertidor debe implementar IMultiValueConverter y estar vinculado al tamaño real y al radio de la esquina, por ejemplo.

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();
}
}

Uso:

<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>

6 para la respuesta № 2

También hay una solución XAML solo para su problema mediante el uso de OpacityMask propiedad. El truco es crear un Grid dentro del borde exterior y establezca la máscara de opacidad de la cuadrícula en otro elemento que actúe como una máscara de recorte.

<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>

En el fragmento de arriba he usado un Border como máscara de recorte, pero también puede ser otro elemento siempre que su color de relleno no sea transparente. Tenga en cuenta también que el borde de clipMask también tiene el mismo CornerRadius.

Inspirado por: http://www.codeproject.com/Articles/225076/Creating-Inner-Shadows-for-WPF-and-Silverlight


1 para la respuesta № 3

ClipToBounds Es la propiedad que podría ayudar en este caso.

Editar: Después de algunas pruebas, me di cuenta de que a ClipToBounds solo le importan los límites reales (es decir, el área rectangular que usa el control), por lo que el contenido aún sobresale en las esquinas ...

Esto parece sugerir que simple recorte a la frontera no es posible. Usted podría establecer la Clip propiedad a un rectángulo redondeado, esto no es muy conveniente porque creo que su tamaño no puede ser limitado.

Tus opciones parecen estar usando un OpacityMask junto con un VisualBrush o recreando un recorte siempre que las propiedades relevantes cambien al usar MultiBinding y MultiValueConverter ...