52 votes

Comment faire pour que le contenu d'une bordure à coins arrondis soit également à coins arrondis?

J'ai un élément de bordure aux coins arrondis contenant une grille 3x3. Les coins de la grille dépassent de la frontière. Comment puis-je résoudre ce problème? J'ai essayé d'utiliser ClipToBounds mais je n'ai rien obtenu. Merci de votre aide

57voto

Micah Points 28683

Voici les faits saillants de ce thread mentionné par Jobi

  • Aucun des décorateurs (c'est à dire la Frontière) ou la mise en page des panneaux (c'est à dire Stackpanel) viennent avec ce comportement out-of-the-box.
  • ClipToBounds est pour la mise en page. ClipToBounds n'empêche pas un élément de dessin à l'extérieur de ses limites; il empêche les enfants de mises en page à partir de 'renverser'. En outre ClipToBounds=True n'est pas nécessaire pour la plupart des éléments en raison de leur mise en œuvre ne permettent de leur contenu, de la présentation du déversement de toute façon. L'exception la plus notable est la Toile.
  • Enfin Frontière considère les coins arrondis pour être des dessins à l'intérieur des limites de sa mise en page.

Voici une implémentation d'une classe qui hérite de la Frontière et met en œuvre la bonne fonctionnalité:

     /// <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;
    }

8voto

Artru Points 737

Comme Michée mentionné ClipToBounds ne fonctionnera pas avec Border.ConerRadius.

Il est UIElement.Clip de la propriété, qui Border des héritages.

Si vous connaissez la taille exacte de la frontière, alors voici la solution:

<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 la taille n'est pas connue ou dynamiques Converter pour Border.Clip peut être utilisé. Voir la solution ici.

7voto

DXM Points 2519

Je suis donc venu à travers cette solution, puis dans msdn lien du forum que Jobi fourni et a passé 20 minutes à écrire ma propre ClippingBorder de contrôle.

Puis j'ai réalisé que CornerRadius type de propriété n'est pas un double, mais le Système.De Windows.CornerRaduis qui accepte de 4 chambres doubles, une pour chaque coin.

Je vais donc à la liste une autre solution alternative à maintenant, ce qui sera plus susceptible de satisfaire les exigences de la plupart des gens qui vont tomber sur ce post à l'avenir...

Disons que vous avez XAML qui ressemble à ceci:

<Border CornerRadius="10">
    <Grid>
        ... your UI ...
    </Grid>
</Border>

Et le problème, c'est que l'arrière-plan de l'élément de Grille saigne à travers et montre passé les coins arrondis. Assurez-vous que votre <Grid> a fond transparent au lieu d'attribuer le même pinceau pour le "Fond" de la propriété de l' <Border> élément. Pas plus de saignements passé les coins et pas besoin de tout un tas de CustomControl code.

C'est vrai qu'en théorie, la zone client ont toujours le potentiel de dessin-delà du bord du coin, mais vous avez le contrôle de ce contenu pour vous en tant que développeur doit être capable de disposer de suffisamment de rembourrage, ou assurez-vous que la forme du contrôle à côté de l'arête est approprié (dans mon cas, mes boutons sont de forme ronde, de sorte s'intègrent très bien dans le coin sans aucun problème).

2voto

Jobi Joy Points 20883

Consultez ce fil qui traite du même sujet.

0voto

Vilx- Points 37939

Rendre la grille plus petite ou la bordure plus grande. Pour que l'élément de bordure contienne complètement la grille.

Vous pouvez également voir si vous pouvez rendre l'arrière-plan de la grille transparent, de sorte que le "dépassement" ne soit pas perceptible.

Mise à jour: Oups, je n'ai pas remarqué qu'il s'agissait d'une question WPF. Je ne connais pas ça. C'était un conseil général HTML / CSS. Peut-être que ça aide ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X