【问题标题】:Independently resizing children in Grid or Stackpanel在 Grid 或 Stackpanel 中独立调整子项的大小
【发布时间】:2011-06-05 13:48:53
【问题描述】:

我想要在触控应用程序的控件中显示图像。除了图像之外,还有一个文本框显示在其下方,作为一个选项卡,停靠在图像的左下方。选项卡的宽度小于图像。用户可以调整、移动和旋转图像,但我希望文本框选项卡保持与图像相同的大小和相同的相对位置。

我尝试过同时使用 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>

我想要做的是允许用户拖动图像(第一个孩子)并调整其大小,同时保持 TextBlock(第二个​​孩子)的大小和相对位置。所以效果是一个固定在图像左下角的选项卡,它是固定的,因为图像可以动态调整大小。

我尝试添加图像以使其更清晰,但作为新用户我不能,抱歉!

【问题讨论】:

  • 如果你能展示一些简单的 xaml 来证明你的观点会有所帮助
  • 这还不够用,你打算如何应用转换?或者你想使用一些 Blend 行为?
  • 目前我正在使用根据触摸事件生成的矩阵变换:matrix.ScaleAt(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.Y, centre.X, centre.Y); i.RenderTransform = new MatrixTransform(matrix);
  • 嗯,如果您的 TextBlock 部分依赖于 Image 的变换,您应该尝试将其拆分为具有 Rotate、Scale 和 Translate 变换的 TransformGroup,您可以这样做吗?
  • 是的-好吧,有点!我一直在搞砸这件事,但收效甚微。我想我希望有某种方法可以在 Grid/StackPanel/Whatever XAML 中指定诸如“保持这个固定大小/宽度”之类的东西,让生活变得轻松:-)

标签: wpf scale children


【解决方案1】:

具有讽刺意味的是,您在 XAML 中使用 DockPanel 替换帖子中的图像。 :) 我认为这正是你想要的——一个 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>

所以这里的想法是,您在画布中的图像位置数据绑定到代码隐藏中的属性。同样,TabControl 的Margin 属性数据绑定到同一属性。但是为了使用它,您需要在后面的代码中编写一个IValueConverter,这个转换器将获取ImageX 的值并返回一个使用ImageX 作为其左边距的新Thickness 对象。

例如

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
}

【讨论】:

  • 请注意指定应该保持文本相对位置的部分,我认为这太静态了,不符合提问者的想法。
  • @H.B.谢谢,所以我猜他是说如果用户在画布中从左到右移动图像,标签的位置需要跟随它?
  • 是的,我认为它应该是一个跟随图像的标签。
  • 没错,没错。用户可以移动、旋转和调整图像大小,文本框/选项卡保持相同大小,锚定在图像的左下角。 “左下角”是指原始的左下角,因此它会随图像旋转。
  • @Will doh,我想即使我的编辑也无济于事。那么当图像旋转时,您希望 TabControl 随之旋转吗?如果是这种情况,那么我认为您想做我列出的操作,但是您需要将所有内容包装在容器中,然后将旋转角度数据绑定到 RotateTransformation。
【解决方案2】:

Will 再次出现:LayoutTransform 是一个非常简单的解决方案。我将主图像和标签放入堆栈面板。然后我将缩放变换作为 LayoutTransform 而不是 RenderTransform 应用到图像,并将 Translate 和 Rotate 变换应用到堆栈面板。问题解决了:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多