2 Stimmen

Silverlight beschneidet UserControl, wenn übergeordnete Spaltenbreite auf GridUnitType.Star gesetzt ist

Ich habe eine Benutzersteuerung, die eine Ellipse enthält. Die Ellipse wird nach rechts transformiert, bis sie teilweise außerhalb ihres übergeordneten Steuerelements liegt.

Ich habe die Benutzersteuerung in die mittlere Spalte eines 3-Spalten-Rasters gesetzt.

Wenn ich die Spaltenbreite auf GridUnitType.Auto einstelle, kann ich sehen, dass die Ellipse die Spalte überfüllt. Wenn ich die Spaltenbreite auf GridUnitType.Star einstelle, läuft die Ellipse zwar immer noch über die Spalte hinaus, aber sie wird jetzt auf die Spaltenbreite abgeschnitten.

Ich muss die Spaltenbreiten mit GridUnitType.Star gleichmäßig verteilen, möchte aber nicht, dass transformierte Inhalte abgeschnitten werden.

Ich habe den Beispielcode unten eingefügt. Jede Hilfe würde geschätzt werden.

UserControl (enthält Ellipse)

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="GridWidthTest.UserControl1">

<Grid x:Name="LayoutRoot" Background="Green">
    <Ellipse Fill="#FFF40404" Stroke="Black" Grid.Column="1" Width="400" Height="400" RenderTransformOrigin="0.5,0.5">
        <Ellipse.RenderTransform>
            <TransformGroup>
                <TranslateTransform X="200"/>
            </TransformGroup>
        </Ellipse.RenderTransform>
    </Ellipse>          
</Grid>

Übergeordnetes Steuerelement (enthält das Gitter)

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GridWidthTest" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="GridWidthTest.MainPage"
Width="640" Height="480" mc:Ignorable="d">

<Grid x:Name="LayoutRoot" Background="White">

    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>           

        <local:UserControl1 Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>             
    </Grid>         
</Grid>

1voto

Vielen Dank für die Antwort.

Ich habe dieses Problem jetzt gelöst, indem ich die Ellipse in ein Canvas eingepackt habe, was bedeutet, dass sie nicht beschnitten wird.

0voto

AnthonyWJones Punkte 182582

Dieses Problem ist äußerst schwierig zu lösen. Zunächst ist es wichtig zu verstehen, was RenderTransform tatsächlich tut. Sie verwandelt, was bisher wurde gerendert. Jedes Pixel wird auf der Grundlage einer letztlich recht einfachen Matrixberechnung an eine neue Position verschoben. Dies geschieht recht spät im gesamten Rendering-Prozess. Die Ellipse ist bereits beschnitten worden antes de die Transformation angewendet wird.

Die Layout-Engine durchläuft zwei Phasen, Maßnahme wo die Elemente um ihre bevorzugten Bedingungen konkurrieren (die Ellipse möchte ein 400 x 400 großes Feld zum Rendern), dann arrangieren. wo den Elementen durch ihre Behälter mitgeteilt wird, was sie tatsächlich haben können.

Wenn die Spaltenbreite "Auto" ist, wird die Grid weicht dem UserControl Anfrage während der Messphase für ein Feld der Breite 400. Die Ellipse wird ohne Beschneidung gerendert, da der Rahmen groß genug ist dann die RenderTransform überträgt die Ergebnisse in eine neue Position.

Wenn die Spaltenbreite "*" ist, wird die Grid gibt dem UserControl nur ein Feld mit einer Breite, die durch den Anteil dieser Spalte an der verfügbaren Breite bestimmt wird, auch wenn dieser kleiner ist als der UserControl gewünschte Breite. In diesem Fall wird die Ellipse gerendert, muss aber an den Rand des angegebenen Rahmens angepasst werden. Seine dann dass diese beschnittene Ellipse an eine neue Position übersetzt wird.

Um aus dem vorgegebenen Rahmen ausbrechen zu können, kann ein Element negative Ränder angeben. Dies führt zu einer größeren Box, die gerendert wird. Wenn zum Beispiel der Container angibt, dass die Breite nur 200 beträgt, die UserControl einen Rand von -100 hat, ist der tatsächlich gerenderte Kasten 400 Pixel breit.

Dies so hinzubekommen, dass es wie erwartet funktioniert und gleichzeitig das dynamische Anordnen von Inhalten unterstützt, kann eine Art von Trial-and-Error-Übung sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X