1

I have an image I want to display in a control in a touch application. As well as the image there is a textbox to display underneath it, as a tab, docked at the bottom left of the image. The tab has a lower width than the image. The user can resize, move and rotate the image, but I'd like the textbox tab to stay the same size and in the same relative position to the image.

I've tried using both a StackPanel and a Grid, but both times the textbox/tab is scaled up as well as the image.

Are either a Grid or StackPanel the way to go, and if so how can I enforce the size of the textbox/tab (that is, the second child) as the size of the first child changes?

Thanks!

In respones to Lars:

 <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>

What I want to do is allow the user to drag and resize the Image(1st child), while maintaining the size and relative position of the TextBlock (2nd child). So the effect is of a tab anchored to the bottom left of the image that is fixed as the image can dynamically resize.

I tried to add images to make this clearer but as a new user I can't, sorry!

Will
  • 11
  • 3
  • 2
    It would help if you would show some simple xaml to demonstrate your point – Lars Truijens Jun 05 '11 at 13:51
  • This is still not really enough to work with, how do you intend to apply transformations? Or do you want to use some Blend behaviours? – H.B. Jun 05 '11 at 14:25
  • At the moment I'm using matrix transformations generated according to touch events: `matrix.ScaleAt(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.Y, centre.X, centre.Y); i.RenderTransform = new MatrixTransform(matrix);` – Will Jun 05 '11 at 14:29
  • Hmm, if your TextBlock is to be partially dependent on the Image's transform you should try to split it up into a TransformGroup which has a Rotate, Scale and Translate transform, can you do that? – H.B. Jun 05 '11 at 14:31
  • Yes- well, sort of! I've been messing about with that with limited success. I guess I was hoping that there's some way to specify in Grid/StackPanel/Whatever XAML something like "keep this bit this fixed size/width" and make life easy :-) – Will Jun 05 '11 at 14:34

2 Answers2

0

It's ironic that you used a DockPanel in your XAML replacement for an image in your post. :) I think that's really what you want here -- a DockPanel with the top portion that scales its contents, and a lower portion that doesn't.

The key is to add the image container to the DockPanel last, so that it automatically is given the rest of the screen real estate. And set its Dock property to "Top".

e.g. (I haven't tested this, BTW. I am just thinking that this will work a little better than what I posted earlier)

<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>

So the idea here is that your image position in the canvas is databound to a property in code-behind. Likewise, the TabControl's Margin property is databound to this same property. But in order to use it, you'll need to write an IValueConverter in code behind, and this converter will take the value of ImageX and return a new Thickness object that uses ImageX as its left margin.

e.g.

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
}
Dave
  • 14,618
  • 13
  • 91
  • 145
  • Note the section which specifies that the relative position of the text should be maintained, i think this is too static and does not fit what the asker has in mind. – H.B. Jun 05 '11 at 14:29
  • @H.B. thanks, so I guess he's saying that if the user moves the image from left to right in a Canvas, the position of the tab needs to follow it? – Dave Jun 05 '11 at 14:43
  • Yes, i think it's supposed to be a label that follows the image around. – H.B. Jun 05 '11 at 14:45
  • That's right, yes. The user can move, rotate, and resize the image, and the textbox/tab stays the same size, anchored to the bottom left of the image. By 'bottom left' I mean the original bottom left, so it rotates with the image. – Will Jun 05 '11 at 14:48
  • @Will doh, I guess even my edit won't help. So when the image is rotated, you want the TabControl to rotate with it? If that's the case, then I think you want to do what I have listed, but you need to wrap everything inside of a container and then databind the rotation angle to a RotateTransformation. – Dave Jun 05 '11 at 14:54
  • Thanks all for the help and the speedy replies. There are a couple of things here to be going on for now with so I'm going to have a look at Dave and HB's suggestions. I'll post up when I've got it sorted! – Will Jun 05 '11 at 15:04
0

Will here again: LayoutTransform was a much, much simpler solution to this. I put the main image and the label into a stackpanel. Then I applied the scale transform to the image as a LayoutTransform rather than a RenderTransform, and applied the Translate and Rotate transforms to the stackpanel. Problem solved :-)

user814425
  • 605
  • 8
  • 19