无法绑定Margin属性?

发布于 2024-10-15 19:21:34 字数 1959 浏览 0 评论 0原文

我正在尝试制作一种动画电影片段,其中在给定时刻只有一个字段可见。就像相机中的胶片一样 - 当前只有一个胶片场放置在镜头下方并准备被照亮。我尝试将其实现为一个带有另一个网格的网格。 “Film strip”在下面的代码中称为 pageContainer。在后面的代码中,我做了一个动画,它改变了 pageContainer 网格的 Margin 属性。工作完美,pageContainer 可以按照我的意愿很好地向左或向右滑动。例如:显示页码。 2 边距设置为 (-270,0,0,0) 而不是 (0,0,0,0)。这会将 pageContainer 移至左侧,并且只有第二个字段可见,而不是第一个字段。

然而,一旦我开始调整整个 UI 的大小,这种机制就会停止工作,用户可以看到两个页面(字段)之间的边框,而不仅仅是当前页面。如果我在 pageWidthConverter 上放置断点,则在调整整个 UI 大小时总会遇到该断点。如果我在 pageMarginConverter 中放置另一个断点,则在调整大小期间永远不会命中它。为什么?我想让 Margin 属性依赖于 BackgroundRectangle ActualWidth,就像我使用 Width 属性一样。但这是行不通的。为什么在调整窗口大小时动态设置宽度,但边距却不是?

PS:除了使用 Margin 之外,还可以使用 TranslateTransform。我尝试过但也没有成功。

如果有人可以提供帮助,我们将不胜感激。

干杯 汉斯

        ... <Grid Grid.Row="3" Grid.Column="1" Margin="0,-4,0,0" ClipToBounds="True">
                <Grid x:Name="pageContainer"
                      Width="{Binding Converter={StaticResource pageWidthConvertor}, ElementName=BackgroundRectangle, Path=ActualWidth}"
                      Margin="{Binding Converter={StaticResource pageMarginConvertor}, ElementName=BackgroundRectangle, Path=ActualWidth}" >

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                    </Grid.ColumnDefinitions> ...

I am trying to have a sort of animated film strip where only one of its fields is visible at the given moment. Like a film strip in a camera - only one film field is currently placed under the lens and prepared to be enlighted. I try to achieve it as a grid withing an another grid. "Film strip" is called pageContainer in the code below. In the code behind I do an animation which is changing the Margin property of pageContainer grid. Works perfectly, pageContainer is nicely sliding to the left or to the right as I wish. For example: To show the page no. 2 the margin is set to (-270,0,0,0) instead of (0,0,0,0). That moves pageContainer to the left and only the second field is visible instead of the first one.

However as soon as I start resizing the whole UI, this mechanism stops to work and user can see a border between the two pages (fields) instead of only the current one. If I put breakpoint to my pageWidthConverter it is always hit when resizing the whole UI. If I put another breakpoint to pageMarginConverter it is never hit during the resizing. Why? I would like to make the Margin property dependent on BackgroundRectangle ActualWidth similarly as I made it with the Width property. But that does not work. Why is Width dynamically set while resizing the window, but Margin is not???

PS: Instead of using Margin one could use TranslateTransform. I tried but no success either.

If anybody can help it would be so highly appreciated.

Cheers
Hans

        ... <Grid Grid.Row="3" Grid.Column="1" Margin="0,-4,0,0" ClipToBounds="True">
                <Grid x:Name="pageContainer"
                      Width="{Binding Converter={StaticResource pageWidthConvertor}, ElementName=BackgroundRectangle, Path=ActualWidth}"
                      Margin="{Binding Converter={StaticResource pageMarginConvertor}, ElementName=BackgroundRectangle, Path=ActualWidth}" >

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                        <ColumnDefinition Width="{Binding ElementName=BackgroundRectangle, Path=ActualWidth}"/>
                        <ColumnDefinition Width="40"/>
                    </Grid.ColumnDefinitions> ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦开始←不甜 2024-10-22 19:21:34

听起来你需要你的边距取决于两件事(1)你想要的偏移量和(2)你的实际宽度的一定比例,以便你的 UI 能够很好地缩放。您尝试过使用多重绑定吗?请查看以下文章:

http://www.codeproject.com/KB /WPF/WpfWinFormsBulletGraphs.aspx#layout

这使用多重绑定来根据控件的大小缩放某些值。这是多重绑定:

class ScalingMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
            object parameter, CultureInfo culture)
    {
        if (!ValuesPopulated(values))
            return 0.0;

        double containerWidth = (double)values[2];
        double valueToScale = (double)values[1];
        double maximum = (double)values[0] ;

        return valueToScale * containerWidth / maximum;
    }

    private bool ValuesPopulated(object[] values)
    {
        foreach (object value in values)
        {
            if (value==null || value.Equals(DependencyProperty.UnsetValue))
                return false;
        }
        return true;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, 
                object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

及其用法示例:

<Rectangle.Width>
    <MultiBinding Converter="{StaticResource ScalingMultiConverter}">
        <Binding Path="(c:BulletGraphWithLegend.GraphRange)"/>
        <Binding Path="(c:BulletGraphWithLegend.FeaturedMeasure)"/>
        <Binding Path="ActualWidth"/>
    </MultiBinding>
</Rectangle.Width>

您应该能够创建一个多重绑定,它采用所需的偏移量和实际宽度并将其转换为边距。

另一方面,为什么不将 Grid 包装在 Canvas 中并通过 Canvas.Left 属性定位它呢?这样您就不必在转换器中构建厚度。

It sounds like you need your margin to be dependant on two things (1) The offset you desire and (2) some proportion of your ActualWidth, in order for your UI to scale nicely. Have you tried using a MultiBinding? Take a look at the following article:

http://www.codeproject.com/KB/WPF/WpfWinFormsBulletGraphs.aspx#layout

This uses a multi-binding to scale some value based on the size of the control. Here is the multi-binding:

class ScalingMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
            object parameter, CultureInfo culture)
    {
        if (!ValuesPopulated(values))
            return 0.0;

        double containerWidth = (double)values[2];
        double valueToScale = (double)values[1];
        double maximum = (double)values[0] ;

        return valueToScale * containerWidth / maximum;
    }

    private bool ValuesPopulated(object[] values)
    {
        foreach (object value in values)
        {
            if (value==null || value.Equals(DependencyProperty.UnsetValue))
                return false;
        }
        return true;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, 
                object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And an example of its usage:

<Rectangle.Width>
    <MultiBinding Converter="{StaticResource ScalingMultiConverter}">
        <Binding Path="(c:BulletGraphWithLegend.GraphRange)"/>
        <Binding Path="(c:BulletGraphWithLegend.FeaturedMeasure)"/>
        <Binding Path="ActualWidth"/>
    </MultiBinding>
</Rectangle.Width>

You should be able to create a multi-binding that takes your desired offset and the ActualWidth and converts it into a Margin.

On another note, why not wrap your Grid in a Canvas and position it via the Canvas.Left property? This way you will not have to construct a Thickness in your converter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文