WPF MeasureOverride循环 [英] WPF MeasureOverride loop

查看:102
本文介绍了WPF MeasureOverride循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是背景:

创建WPF分割图

我已经决定删除​​scrollviewers,并且只使用一个将会增加基本变化的元素。



我有一个很奇怪的问题需要解决。
这就是这种情况,我以这种方式设置了一些项目。

父母 - >孩子。
ScrollViewer - >画布。
画布 - >网格。
- 网格 - >多个画布(分为不同的网格列)。

 < ScrollViewer x: Name =MainScrollViewHorizo​​ntalScrollBarVisibility =Auto
VerticalScrollBarVisibility =Auto
Horizo​​ntalAlignment =StretchVerticalAlignment =Stretch>

< s:DesignerCanvas Focusable =truex:Name =MyDesignerTop
FocusVisualStyle ={x:Null}IsHitTestVisible =True
Grid.ColumnSpan =2147483647Panel.ZIndex =2147483647
ContextMenu ={StaticResource DesignerCanvasContextMenu}>

< s:DesignerCanvas.Background>
< SolidColorBrush Opacity =0/>
< / s:DesignerCanvas.Background>
< Grid x:Name =MainGridBackground =#FF61B5B9>
< Grid.ColumnDefinitions>
< ColumnDefinition />
< /Grid.ColumnDefinitions>

< s:DesignerCanvas Focusable =truex:Name =MyDesigner
Background ={StaticResource WindowBackgroundBrush}
FocusVisualStyle ={x:Null}宽度=700高度=700
保证金=5/>
<! - ContextMenu ={StaticResource DesignerCanvasContextMenu} - >

< / Grid>
< / s:DesignerCanvas>

< / ScrollViewer>

我会解释一下,我在一个较低的画布上有一个项目,让我们假设我想要将它从一个画布移动到另一个画布,我设法解决这个问题,因为我有更高的租用画布让我可以。



问题是当我想调整大小该项目,让我们假设其中一个较低的画布上的项目之一是走向边缘,我可以重新调整画布,但这对上部网格没有影响(有时它奇怪地),所以我的上部画布不'没有任何效果,所以我的scrollviewer还没有通知增加的大小。



如果我手动告诉网格测量自己,因为其中一个子元素超过划分的画布大小,比它也会告诉它的所有孩子要测量自己,以便将它们返回给它所需的值,这将导致无限循环。

这里是

是MeasureOverride函数:

 保护覆盖尺寸M easureOverride(大小约束)
{
大小大小=新大小();

foreach(UIElement element in this.InternalChildren)
{
double left = Canvas.GetLeft(element);
double top = Canvas.GetTop(element);
left = double.IsNaN(左)? 0:离开;
top = double.IsNaN(顶部)? 0:顶部;

//为每个孩子测量所需的大小
element.Measure(constraint);

大小desiredSize = element.DesiredSize;
if(!double.IsNaN(desiredSize.Width)&&!double.IsNaN(desiredSize.Height))
{
size.Width = Math.Max(size.Width, left + desiredSize.Width);
size.Height = Math.Max(size.Height,top + desiredSize.Height);
}
}
//添加保证金
size.Width + = 10;
size.Height + = 10;

//假设我在这里告诉网格手动测量自己 - >无限循环

返回大小;
}

我该如何解决这个问题?我怎么能通知链中的所有孩子来衡量自己而不会造成无限循环? 解决方案

我奇怪地解决了这个问题。
我没有再使用Width,只是MinWidth,所有的计算都突然被修正了。

 < ScrollViewer x:Name =MainScrollViewHorizo​​ntalScrollBarVisibility =Auto
VerticalScrollBarVisibility =Auto
Horizo​​ntalAlignment =StretchVerticalAlignment =Stretch>

< s:DesignerCanvas Focusable =truex:Name =MyDesignerTop
FocusVisualStyle ={x:Null}IsHitTestVisible =True
Grid.ColumnSpan =2147483647Panel.ZIndex =2147483647
ContextMenu ={StaticResource DesignerCanvasContextMenu}>

< s:DesignerCanvas.Background>
< SolidColorBrush Opacity =0/>
< / s:DesignerCanvas.Background>
< Grid x:Name =MainGridBackground =#FF61B5B9>
< Grid.ColumnDefinitions>
< ColumnDefinition />
< /Grid.ColumnDefinitions>

< s:DesignerCanvas Focusable =truex:Name =MyDesigner
Background ={StaticResource WindowBackgroundBrush}
FocusVisualStyle ={x:Null} MinWidth =600MinHeight =600
Margin =5/>
<! - ContextMenu ={StaticResource DesignerCanvasContextMenu} - >

< / Grid>
< / s:DesignerCanvas>

< / ScrollViewer>


This is the background:
Creating a WPF divided diagram
I've decided to remove the scrollviewers, and use only one that will increase by the base one changes.

I have quite a strange issue to resolve. This is the case, I have a set up of items in this way.
Parent -> Child.
ScrollViewer -> Canvas.
Canvas -> Grid.
Grid -> Multiple Canvases (divided to different grid columns).

<ScrollViewer x:Name="MainScrollView" HorizontalScrollBarVisibility="Auto"
                        VerticalScrollBarVisibility="Auto"
                        HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

                <s:DesignerCanvas Focusable="true" x:Name="MyDesignerTop"
                        FocusVisualStyle="{x:Null}" IsHitTestVisible="True"
                        Grid.ColumnSpan="2147483647" Panel.ZIndex="2147483647"
                        ContextMenu="{StaticResource DesignerCanvasContextMenu}">

                    <s:DesignerCanvas.Background>
                        <SolidColorBrush Opacity="0"/>
                    </s:DesignerCanvas.Background>
                    <Grid x:Name="MainGrid" Background="#FF61B5B9">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>

                        <s:DesignerCanvas Focusable="true" x:Name="MyDesigner"
                        Background="{StaticResource WindowBackgroundBrush}"
                        FocusVisualStyle="{x:Null}" Width="700" Height="700"
                         Margin="5"/>
                        <!--ContextMenu="{StaticResource DesignerCanvasContextMenu}"-->

                    </Grid>
                </s:DesignerCanvas>

</ScrollViewer>

I'll explain, I have an item on one of the lower canvases, and let's assume I want to move it from one canvas to another, I managed to pull that off since I have the higher hirerachy canvas which allow me to.

The problem is when I want to resize the item, let's assume that one of the item on one of the lower canvases is going towards the edge, I can rescale the canvas, however this has no effect on the upper grid (sometime it strangely does), so my upper canvas doesn't have any effect, and so my scrollviewer hasn't notified on the increase of size.

If I manually tell the grid to measure itself since one of the element childs exceed the divided canvas size, than it will also tell to all of it's child to measure themselves in order to return it their desired values, which will cause an infinite loop.

here is the MeasureOverride function:

protected override Size MeasureOverride(Size constraint)
    {
        Size size = new Size();

        foreach (UIElement element in this.InternalChildren)
        {
            double left = Canvas.GetLeft(element);
            double top = Canvas.GetTop(element);
            left = double.IsNaN(left) ? 0 : left;
            top = double.IsNaN(top) ? 0 : top;

            //measure desired size for each child
            element.Measure(constraint);

            Size desiredSize = element.DesiredSize;
            if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
            {
                size.Width = Math.Max(size.Width, left + desiredSize.Width);
                size.Height = Math.Max(size.Height, top + desiredSize.Height);
            }
        }
        // add margin 
        size.Width += 10;
        size.Height += 10;

        //Let's assume here I will tell the grid to manually measure itself -> infinite loop

        return size;
    }

How can I fix this? how can I notify all childs in chain to measure themselves without causing an infinite loop?

解决方案

I strangely fixed the problem. I didn't use Width anymore, just MinWidth instead, and all the calculations were suddenly fixed.

<ScrollViewer x:Name="MainScrollView" HorizontalScrollBarVisibility="Auto"
                        VerticalScrollBarVisibility="Auto"
                        HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

                <s:DesignerCanvas Focusable="true" x:Name="MyDesignerTop"
                        FocusVisualStyle="{x:Null}" IsHitTestVisible="True"
                        Grid.ColumnSpan="2147483647" Panel.ZIndex="2147483647"
                        ContextMenu="{StaticResource DesignerCanvasContextMenu}">

                    <s:DesignerCanvas.Background>
                        <SolidColorBrush Opacity="0"/>
                    </s:DesignerCanvas.Background>
                    <Grid x:Name="MainGrid" Background="#FF61B5B9">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>

                        <s:DesignerCanvas Focusable="true" x:Name="MyDesigner"
                        Background="{StaticResource WindowBackgroundBrush}"
                        FocusVisualStyle="{x:Null}" MinWidth="600" MinHeight="600"
                         Margin="5"/>
                        <!--ContextMenu="{StaticResource DesignerCanvasContextMenu}"-->

                    </Grid>
                </s:DesignerCanvas>

</ScrollViewer>

这篇关于WPF MeasureOverride循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆