<b><!-- Элемент Rectangle с трансформацией поворотом --></b>
<Rectangle Height ="100" Width ="40" Fill ="Red">
<Rectangle.LayoutTransform>
<RotateTransform Angle ="45"/>
</Rectangle.LayoutTransform>
</Rectangle>
Здесь элемент Button скашивается на поверхности на 20 градусов посредством трансформации SkewTransform:
<b><!-- Элемент Button с трансформацией скашиванием --></b>
<Button Content ="Click Me!" Width="95" Height="40">
<Button.LayoutTransform>
<SkewTransform AngleX ="20" AngleY ="20"/>
</Button.LayoutTransform>
</Button>
Для полноты картины ниже приведен элемент Ellipse, масштабированный на 20% с помощью трансформации ScaleTransform (обратите внимание на значения, установленные в свойствах Height и Width), а также элемент TextBox, к которому применена группа объектов трансформации:
<b><!-- Элемент Ellipse, масштабированный на 20% --></b>
<Ellipse Fill ="Blue" Width="5" Height="5">
<Ellipse.LayoutTransform>
<ScaleTransform ScaleX ="20" ScaleY ="20"/>
</Ellipse.LayoutTransform>
</Ellipse>
<b><!-- Элемент TextBox, повернутый и скошенный --></b>
<TextBox Text ="Me Too!" Width="50" Height="40">
<TextBox.LayoutTransform>
<TransformGroup>
<RotateTransform Angle ="45"/>
<SkewTransform AngleX ="5" AngleY ="20"/>
</TransformGroup>
</TextBox.LayoutTransform>
</TextBox>
Следует отметить, что в случае применения трансформации выполнять какие-либо ручные вычисления для реагирования на проверку попадания, перемещение фокуса ввода и аналогичные действия не придется. Графический механизм WPF самостоятельно решает такие задачи. Например, на рис. 26.8 можно видеть, что элемент TextBox по-прежнему реагирует на клавиатурный ввод.
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
Трансформация данных Canvas
Теперь нужно внедрить в пример RenderingWithShapes логику трансформации. Помимо применения объектов трансформации к одиночному элементу (Rectangle, TextBox и т.д.) их можно также применять к диспетчеру компоновки, чтобы трансформировать все внутренние данные. Например, всю панель DockPanel главного окна можно было бы визуализировать под углом:
<DockPanel LastChildFill="True">
<DockPanel.LayoutTransform>
<RotateTransform Angle="45"/>
</DockPanel.LayoutTransform>
...
</DockPanel>
В рассматриваемом примере это несколько чрезмерно, так что добавьте последнюю (менее радикальную) возможность, которая позволит пользователю зеркально отобразить целый контейнер Canvas и всю содержащуюся в нем графику. Начните с добавления в ToolBar финального элемента ToggleButton со следующим определением:
<ToggleButton Name="flipCanvas" Click="FlipCanvas_Click"
Content="Flip Canvas!"/>
Внутри обработчика события Click для нового элемента ToggleButton создайте объект RotateTransform и подключите его к объекту Canvas через свойство LayoutTransform, если элемент ToggleButton отмечен. Если же элемент ToggleButton не отмечен, тогда удалите трансформацию, установив свойство LayoutTransform в null.
private void FlipCanvas_Click(object sender, RoutedEventArgs e)
{
if (flipCanvas.IsChecked == true)
{
RotateTransform rotate = new RotateTransform(-180);
canvasDrawingArea.LayoutTransform = rotate;
}
else
{
canvasDrawingArea.LayoutTransform = null;
}
}
Запустите приложение и добавьте несколько графических фигур в область Canvas, следя за тем, чтобы они находились впритык к ее краям. После щелчка на новой кнопке обнаружится, что фигуры выходят за границы Canvas (рис. 26.9). Причина в том, что не был определен прямоугольник отсечения.