Самостоятельное изменение размера детей в сетке или стеке - PullRequest
1 голос
/ 05 июня 2011

У меня есть изображение, которое я хочу отобразить в элементе управления в сенсорном приложении. Помимо изображения, под ним находится текстовое поле в виде вкладки, закрепленной в левом нижнем углу изображения. Вкладка имеет меньшую ширину, чем изображение. Пользователь может изменять размер, перемещать и поворачивать изображение, но я бы хотел, чтобы вкладка текстового поля оставалась того же размера и в той же относительной позиции к изображению.

Я пробовал использовать как StackPanel, так и Grid, но оба раза текстовое поле / вкладка масштабируется так же, как и изображение.

Является ли Grid или StackPanel подходящим способом, и если да, то как я могу обеспечить размер текстового поля / вкладки (то есть второго дочернего элемента) при изменении размера первого дочернего элемента?

Спасибо!

В ответах Ларса:

 <Grid Name="mygrid" Background="Red" Width="320" Height="300">

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="255"/>
        <RowDefinition MaxHeight="40" />
    </Grid.RowDefinitions>

    <!--Ist child-->
    <Canvas Name="maincanvas" Background="DarkKhaki" Width="300" Height="180" Grid.Row="0">
        <!--<Image goes in here>-->
    </Canvas>

    <!--2nd child-->
    <DockPanel Name="dockpanel" Grid.Row="1"  Background="DarkKhaki" MaxWidth="200" HorizontalAlignment="Left">
        <TextBlock Name="textblock" TextWrapping="Wrap" >
            some text here
        </TextBlock>
    </DockPanel>
</Grid>

Что я хочу сделать, это позволить пользователю перетаскивать и изменять размер изображения (1-й дочерний элемент), сохраняя при этом размер и относительное положение TextBlock (2-й дочерний элемент). Таким образом, эффект имеет вкладку, прикрепленную к левому нижнему углу изображения, которая фиксируется, поскольку изображение может динамически изменять размер.

Я пытался добавить изображения, чтобы сделать это понятнее, но как новый пользователь я не могу, извините!

Ответы [ 2 ]

0 голосов
/ 24 июня 2011

Будет еще раз: LayoutTransform был намного, гораздо более простым решением для этого. Я положил основное изображение и метку в стеке панели. Затем я применил масштабное преобразование к изображению как LayoutTransform, а не RenderTransform, и применил преобразования Translate и Rotate к панели стека. Проблема решена: -)

0 голосов
/ 05 июня 2011

Забавно, что вы использовали DockPanel в качестве замены XAML для изображения в своем посте. :) Я думаю это действительно то, что вы хотите здесь - DockPanel с верхней частью, которая масштабирует ее содержимое, и нижней частью, которая этого не делает.

Ключом является добавление контейнера изображений в DockPanel последним, чтобы ему автоматически предоставлялась оставшаяся часть экрана. И установите для его свойства Dock значение "Top".

например. (Я не проверял это, кстати. Я просто думаю, что это будет работать немного лучше, чем я писал ранее)

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Page.Resources>
    <!-- put LeftMarginConverter here -->
  </Page.Resources>

  <DockPanel>
    <TabControl DockPanel.Dock="Bottom" Margin="{Binding ImageX, Converter={StaticResource LeftMarginConverter}}">
      <TabItem Header="Some text here" />
    </TabControl>
    <Canvas DockPanel.Dock="Top">
      <Image Canvas.Left="{Binding ImageX}">
        <!-- image goes here -->
      </Image>
    </Canvas>
  </DockPanel>
</Page>

Таким образом, идея заключается в том, что позиция вашего изображения на холсте привязана к свойству в выделенном коде. Аналогично, свойство Margin TabControl связано с этим же свойством. Но чтобы его использовать, вам нужно написать IValueConverter в коде позади, и этот преобразователь примет значение ImageX и вернет новый объект Thickness, который использует ImageX в качестве левого поля.

, например

public class LeftMarginConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int left_margin = object as int;
        return new Thickness( left_margin,0,0,0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // we aren't ever going to need to convert back for this formatter!
        return null;
    }

    #endregion
}
...