Tengo un elemento de borde con esquinas redondeadas que contiene una cuadrícula de 3x3. Las esquinas de la cuadrícula sobresalen del borde. ¿Cómo puedo arreglar eso? Intenté usar ClipToBounds pero no llegué a ningún lado. Gracias por su ayuda¿Cómo hacer que el contenido de un borde redondo esté también redondeado?
Respuesta
Éstos son los aspectos más destacados de esta thread mencionados por Jobi
- Ninguno de los decoradores (es decir Frontera) o paneles de diseño (es decir StackPanel) vienen con este comportamiento fuera de la -caja.
- ClipToBounds es para el diseño. ClipToBounds no evita que un elemento se dibuje fuera de sus límites; solo evita que los diseños de los niños se "derramen". Además ClipToBounds = True no es necesario para la mayoría de los elementos porque sus implementaciones no permiten que el diseño de su contenido se derrame de todos modos. La excepción más notable es Canvas.
- Finalmente, Border considera que las esquinas redondeadas son dibujos dentro de los límites de su diseño.
Aquí es una implementación de una clase que hereda de Frontera e implementa el funcionamiento correcto:
/// <Remarks>
/// As a side effect ClippingBorder will surpress any databinding or animation of
/// its childs UIElement.Clip property until the child is removed from ClippingBorder
/// </Remarks>
public class ClippingBorder : Border {
protected override void OnRender(DrawingContext dc) {
OnApplyChildClip();
base.OnRender(dc);
}
public override UIElement Child
{
get
{
return base.Child;
}
set
{
if (this.Child != value)
{
if(this.Child != null)
{
// Restore original clipping
this.Child.SetValue(UIElement.ClipProperty, _oldClip);
}
if(value != null)
{
_oldClip = value.ReadLocalValue(UIElement.ClipProperty);
}
else
{
// If we dont set it to null we could leak a Geometry object
_oldClip = null;
}
base.Child = value;
}
}
}
protected virtual void OnApplyChildClip()
{
UIElement child = this.Child;
if(child != null)
{
_clipRect.RadiusX = _clipRect.RadiusY = Math.Max(0.0, this.CornerRadius.TopLeft - (this.BorderThickness.Left * 0.5));
_clipRect.Rect = new Rect(Child.RenderSize);
child.Clip = _clipRect;
}
}
private RectangleGeometry _clipRect = new RectangleGeometry();
private object _oldClip;
}
Haga la rejilla más pequeña o el borde más grande. De modo que el elemento de borde contiene completamente la cuadrícula.
Como alternativa, vea si puede hacer que el fondo de la cuadrícula sea transparente, para que no se note el "salido".
Actualización: Vaya, no noté que esta era una pregunta de WPF. No estoy familiarizado con eso. Este fue un consejo general de HTML/CSS. Tal vez ayude ...
Pero tienes razón en que es una respuesta lógica, y también funciona en muchas situaciones en WPF. –
Así que me encontré con esta solución, a continuación, seguido en enlace del foro de MSDN que Jobi siempre y pasó 20 minutos escribiendo mi propio control ClippingBorder.
Luego me di cuenta de que el tipo de propiedad CornerRadius no es un doble, sino System.Windows.CornerRaduis que acepta 4 dobles, uno para cada esquina.
así que voy a enumerar otra solución alternativa ahora, que lo más probable es satisfacer las necesidades de la mayoría de personas que van a tropezar con este post en el futuro ...
Digamos que usted tiene XAML que se parece esto:
<Border CornerRadius="10">
<Grid>
... your UI ...
</Grid>
</Border>
y el problema es que el fondo del elemento de cuadrícula sangra a través y muestra más allá de las esquinas redondeadas. Asegúrese de que su <Grid>
tenga fondo transparente en lugar de asignar el mismo pincel a la propiedad "Fondo" del elemento <Border>
. No más sangrado más allá de las esquinas y sin necesidad de un montón de código CustomControl.
Es cierto que, en teoría, el área del cliente todavía tiene el potencial de atravesar el borde de la esquina, pero usted controla ese contenido para que usted, como desarrollador, tenga suficiente relleno o para asegurarse de que la forma del el control al lado del borde es apropiado (en mi caso, mis botones son redondos, por lo que se ajustan muy bien en la esquina sin ningún problema).
Como mencionó Micah ClipToBounds
no funcionará con Border.ConerRadius
.
Hay UIElement.Clip propiedad, que Border
herencias.
Si conoce el tamaño exacto de la frontera, entonces aquí es la solución:
<Border Background="Blue" CornerRadius="3" Height="100" Width="100">
<Border.Clip>
<RectangleGeometry RadiusX="3" RadiusY="3" Rect="0,0,100,100"/>
</Border.Clip>
<Grid Background="Green"/>
</Border>
Si el tamaño no es conocido o dinámico continuación Converter
para Border.Clip
se puede utilizar. Vea la solución here.
XAML puro:
<Border CornerRadius="30" Background="Green">
<Border.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<Border
Background="Black"
SnapsToDevicePixels="True"
CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource AncestorType=Border}}"
Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Border}}"
Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Border}}"
/>
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
<TextBlock Text="asdas das d asd a sd a sda" />
</Border>
Actualización: encontrado una mejor manera de conseguir el mismo resultado. También puede reemplazar Border con cualquier otro elemento ahora.
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Border1}" />
</Grid.OpacityMask>
<Border x:Name="Border1" CornerRadius="30" Background="Green" />
<TextBlock Text="asdas das d asd a sd a sda" />
</Grid>
Para deshacerse de los artefactos que se encuentran detrás de las esquinas redondeadas en el primer ejemplo (que se puede ver cuando se amplía con la herramienta Snoop, por ejemplo) también debe vincular BorderThickness (de la misma manera) y establecer BorderBrush en Blanco. Esto cortará el borde de la frontera. –
El primer ejemplo es más general porque puede ser transparente (la forma de recorte no tiene que ser visible, con su fondo). –
Utilizando la solución de @ Andrew Mikhailov, se puede definir una clase simple, lo que hace que la definición de un VisualBrush
para cada elemento afectado innecesaria manualmente:
public class ClippedBorder : Border
{
public ClippedBorder() : base()
{
var e = new Border()
{
Background = Brushes.Black,
SnapsToDevicePixels = true,
};
e.SetBinding(Border.CornerRadiusProperty, new Binding()
{
Mode = BindingMode.OneWay,
Path = new PropertyPath("CornerRadius"),
Source = this
});
e.SetBinding(Border.HeightProperty, new Binding()
{
Mode = BindingMode.OneWay,
Path = new PropertyPath("ActualHeight"),
Source = this
});
e.SetBinding(Border.WidthProperty, new Binding()
{
Mode = BindingMode.OneWay,
Path = new PropertyPath("ActualWidth"),
Source = this
});
OpacityMask = new VisualBrush(e);
}
}
Para probar esto, simplemente compilar las dos muestras siguientes:
<!-- You should see a blue rectangle with rounded corners/no red! -->
<Controls:ClippedBorder
Background="Red"
CornerRadius="10"
Height="425"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="425">
<Border Background="Blue">
</Border>
</Controls:ClippedBorder>
<!-- You should see a blue rectangle with NO rounded corners/still no red! -->
<Border
Background="Red"
CornerRadius="10"
Height="425"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="425">
<Border Background="Blue">
</Border>
</Border>
- 1. UIButton de rectángulo redondeado sin el borde
- 2. Borde redondeado en un solo lado java
- 3. ¿Cómo puedo tener un borde redondeado en mi mesa y un colapso de borde: colapsar?
- 4. UItextfiled cómo hacer el radio del borde y mantener la sombra del borde también radio
- 5. Haga que el borde inferior esté más cerca del texto
- 6. Android: ¿Cómo hacer que el teclado siempre esté visible?
- 7. borde div que no rodea el contenido
- 8. ¿Cómo hacer que RibbonApplicationMenuBar esté inactivo/activo?
- 9. Cómo "z-index" para hacer que un menú esté siempre en la parte superior del contenido
- 10. Cómo hacer que el sitio web esté disponible sin conexión
- 11. cómo hacer que JDialog esté inactivo
- 12. Cómo hacer que un proyecto "repositorio/equipo" esté listo
- 13. Cómo hacer que un sitio web esté protegido con https
- 14. cómo hacer que el texto de UITextField esté seleccionado Prográficamente
- 15. ¿Por qué no puedo crear el borde redondo para una esquina específica?
- 16. border-radius en <th>. Sin borde redondeado
- 17. ¿Cómo hacer textView redondeado en Android?
- 18. jQuery, ocultar el contenido hasta que esté cargada
- 19. Cómo dibujar un rectángulo redondeado con un borde de ancho variable dentro de límites específicos
- 20. ¿Cómo hacer que un div crezca con el contenido?
- 21. Overflow-x: hidden también oculta el contenido vertical también
- 22. Haz un botón redondo
- 23. Cómo colocar imágenes de borde redondo en Outlook de forma predeterminada
- 24. ¿Cómo hacer que el borde recorte los elementos secundarios?
- 25. Qt 4.6 QLineEdit Style. ¿Cómo doy estilo al borde resaltado gris para que quede redondeado?
- 26. ¿Qué hace que Categoría esté implementando un método que también será implementado por su clase principal?
- 27. Cómo hacer que un cuadro de texto esté vacío en el código detrás de
- 28. ¿Cómo hacer que una aplicación GPO esté al tanto?
- 29. ¿Puedes hacer "un borde invisible"?
- 30. ¿Cómo puedo hacer un diseño de borde usando css?
Esta solución usa un convertidor en lugar de crear una nueva clase: http://stackoverflow.com/questions/5649875/how-to-make-the-border-trim-the-child-elements Nota: tuve que anidar en el borde objetos para retener mi borde de color (el fondo funciona bien sin anidar) –
¿Podría explicar la lógica en su código? Parece que no puedo entender el propósito de '_oldClip' y por qué está eligiendo' RadiusX' y 'RadiusY' para que sean' this.CornerRadius.TopLeft - (this.BorderThickness.Left * 0.5) '. –