Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何防止这种布局循环?_C#_.net_Silverlight_Xaml_Layout - Fatal编程技术网

C# 如何防止这种布局循环?

C# 如何防止这种布局循环?,c#,.net,silverlight,xaml,layout,C#,.net,Silverlight,Xaml,Layout,图中显示了这些小间隙。间隙之间的蓝色大容器是内容夹,其宽度由确定。红色边框是可调整大小的支架 因此,两个外部间隙描述了红色支架的左右填充。每个容器旁边的两个间隙是每个容器的左右边距 每次我调整支架的大小时,它的SizeChanged事件都会引发 gapsize=(holderWidth-所有容器的总宽度)/numberOfGaps 我通过ActualWidth(UIElement)属性获取holderWidth。每次引发SizeChanged事件时,我都会重新绑定(Silverlight hac

图中显示了这些小间隙。间隙之间的蓝色大容器是内容夹,其宽度由确定。红色边框是可调整大小的支架

因此,两个外部间隙描述了红色支架的左右填充。每个容器旁边的两个间隙是每个容器的左右边距

每次我调整支架的大小时,它的
SizeChanged
事件都会引发

gapsize=(holderWidth-所有容器的总宽度)/numberOfGaps

我通过
ActualWidth
(UIElement)属性获取holderWidth。每次引发
SizeChanged
事件时,我都会重新绑定(Silverlight hack)每个容器的MarginProperty持有者的padding属性(
UpdateTarget
在Silverlight中不起作用,
INotifyPropertyChanged
不可用)。这是在
UpdateMargins()
方法中完成的,该方法在
SizeChanged
事件处理程序中调用

我试图通过比较以前的页边距和新的页边距来防止不可见的页边距刷新(小于一个像素)

但是使用这种方法,我会不时地引起布局周期。现在我只想问一下是否有逻辑错误。我读过博客,并试图用这种方法解决它。但这些布局周期仍然存在


我这样做是为了在每次调整内容持有者的大小时将其置于中心位置(容器)。我知道两列网格也是一个可行的解决方案。但问题是红色的容器必须是一个包装,在这种情况下,第二个蓝色的容器跳到第一个容器的下面,如果支架太小,无法彼此相邻显示。

在我看来,在SizeChanged事件中更改视觉树上的任何内容都可能最终导致性能问题,因为如果您不小心会调用多个布局周期(这似乎与您描述的问题一致)

如果您需要以特定方式布局内容,我建议您创建一个新面板,并覆盖布局周期中使用的ArrangeOverride和MeasureOverride方法。您可以使用现有的WrapPanel源代码(可从Ms Pl下的CodePlex下载),并根据需要更改逻辑以布局内容

网上有很多关于创建自定义面板和Silverlight布局周期的文章


很抱歉,我无法直接帮助解决您的问题,但希望此信息对您有所帮助

在我看来,在SizeChanged事件中更改视觉树上的任何内容最终都会给您带来性能问题,因为如果您不小心,会调用多个布局周期(这似乎与您描述的问题一致)

如果您需要以特定方式布局内容,我建议您创建一个新面板,并覆盖布局周期中使用的ArrangeOverride和MeasureOverride方法。您可以使用现有的WrapPanel源代码(可从Ms Pl下的CodePlex下载),并根据需要更改布局内容的逻辑

网上有很多关于创建自定义面板和Silverlight布局周期的文章


很抱歉,我无法直接帮助解决您的问题,但希望这些信息对您有所帮助。

创建一个面板来满足您的需要并不困难。下面的示例为每个孩子提供了相同的空间:

using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace GapPanel
{
    public class GapPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            if (Children.Count == 0)
                return base.MeasureOverride(availableSize);
            // allot equal space to each child; you may want different logic 
            var spacePerChild = new Size(availableSize.Width / Children.Count,
                                         availableSize.Height);
            foreach (var child in Children)
                child.Measure(spacePerChild);
            var totalWidth = Children.Sum(child => child.DesiredSize.Width);
            var maxHeight = Children.Max(child => child.DesiredSize.Height);
            return new Size(totalWidth, maxHeight);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            if (Children.Count == 0)
                return base.ArrangeOverride(finalSize);
            var gap = (finalSize.Width - Children.Sum(
                       child => child.DesiredSize.Width)) / (Children.Count + 1);
            var spacePerChild = (finalSize.Width - gap * (Children.Count + 1))
                                / Children.Count;
            for (int i = 0; i < Children.Count; i++)
            {
                var child = Children[i];
                child.Arrange(new Rect(i * spacePerChild + (i + 1) * gap, 0,
                                       spacePerChild, finalSize.Height));
            }
            return finalSize;
        }
    }
}
使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
名称空间GapPanel
{
公共类GapPanel:面板
{
受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
{
如果(Children.Count==0)
返回基准。测量超越(可用尺寸);
//为每个子级分配相等的空间;您可能需要不同的逻辑
var spacepercild=新大小(availableSize.Width/Children.Count,
有效尺寸、高度);
foreach(儿童中的儿童变量)
儿童。测量(空间或水平);
var totalWidth=Children.Sum(child=>child.DesiredSize.Width);
var maxHeight=Children.Max(child=>child.DesiredSize.Height);
返回新尺寸(总宽度、最大高度);
}
受保护的替代尺寸排列替代(尺寸最终化)
{
如果(Children.Count==0)
返回基数。安排覆盖(最终化);
var gap=(finalSize.Width-Children.Sum(
child=>child.DesiredSize.Width))/(Children.Count+1);
var spacepercild=(finalSize.Width-gap*(Children.Count+1))
/孩子们,数一数;
for(int i=0;i
您可以像使用常规面板一样使用它:

<my:GapPanel>
    <Button HorizontalAlignment="Center" Width="200" Height="200">abc!</Button>
    <Button HorizontalAlignment="Center" Width="200" Height="200">foo!</Button>
    <Button HorizontalAlignment="Center" Width="100" Height="200">bar!</Button>
</my:GapPanel>

abc!
福!
酒吧

创建一个面板并不难,它可以简单地满足您的需要。下面的示例为每个孩子提供了相等的空间:

using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace GapPanel
{
    public class GapPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            if (Children.Count == 0)
                return base.MeasureOverride(availableSize);
            // allot equal space to each child; you may want different logic 
            var spacePerChild = new Size(availableSize.Width / Children.Count,
                                         availableSize.Height);
            foreach (var child in Children)
                child.Measure(spacePerChild);
            var totalWidth = Children.Sum(child => child.DesiredSize.Width);
            var maxHeight = Children.Max(child => child.DesiredSize.Height);
            return new Size(totalWidth, maxHeight);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            if (Children.Count == 0)
                return base.ArrangeOverride(finalSize);
            var gap = (finalSize.Width - Children.Sum(
                       child => child.DesiredSize.Width)) / (Children.Count + 1);
            var spacePerChild = (finalSize.Width - gap * (Children.Count + 1))
                                / Children.Count;
            for (int i = 0; i < Children.Count; i++)
            {
                var child = Children[i];
                child.Arrange(new Rect(i * spacePerChild + (i + 1) * gap, 0,
                                       spacePerChild, finalSize.Height));
            }
            return finalSize;
        }
    }
}
使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
名称空间GapPanel
{
公共类GapPanel:面板
{
受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
{
如果(Children.Count==0)
返回基准。测量超越(可用尺寸);
//为每个子级分配相等的空间;您可能需要不同的逻辑
var spacepercild=新大小(availableSize.Width)