代码之家  ›  专栏  ›  技术社区  ›  Wonko the Sane

使用共享大小组测量/排列网格

  •  4
  • Wonko the Sane  · 技术社区  · 14 年前

    两个包含以某种方式指定的元素的网格和sharedSizeGroup似乎有点问题。

    此问题是对 之前的问题的响应 from user d.h. i attempted to answer.请原谅长度,但它有助于直观地演示问题。

    他最初的问题是,当满足某些条件(调整右侧网格中的文本块的大小)时,为什么具有sharedSizeGroup的两个网格没有调整到相同的高度。我举了他的例子并扩展了它,因为我怀疑它与度量/排列循环有关。

    事实证明,它确实与度量和安排有关。实际上,它与执行测量有关。 我觉得这可能至少是一个问题,如果不是bug,但我想对行为进行解释。

    以下是对所发生的情况的快速概述(仅用于演示目的的花哨颜色)。

    启动 两个网格都有三行,每行包含一个文本块。中间一行是sharedsizegroup。中间行的文本绑定到其文本块的实际高度,初始高度属性硬编码为您看到的值。网格下面的数字表示网格的实际高度。请注意,左侧网格的背景色为绿色。

    增加右侧文本块 当右侧网格的大小增加时,您可以看到两个网格由于SharedSizeGroup而调整为新的高度。右边的列反映了网格的度量和排列调用。

    减少右侧文本块,但仍大于左侧文本块 当右侧网格的大小减小,但仍大于左侧硬编码文本块的大小时,您可以看到由于SharedSizeGroup,两个网格再次调整到新高度。右边的列反映了网格的度量和排列调用。

    减少右侧文本块小于左侧文本块的大小 当右侧网格的大小减小,小于左侧硬编码文本块的大小时,您可以看到左侧网格没有减小到“合适”的大小,这可以通过在底部看到网格的绿色背景来证明,并且网格的大小是150而不是130。

    如果您查看右侧的信息,您会注意到左侧网格进行了排列,但 did not do a measure.


    以下是复制问题的示例代码。

    InfoGrid和InfoGridEventArgs类

    使用system.windows; 使用system.windows.controls; 命名空间GridMeasureExample { 类信息网格:网格 { 受保护的覆盖大小排列覆盖(大小排列大小) { callReportInfoEvent(“排列”); 返回base.arrangeoverride(arrangesize); } 受保护的覆盖大小MeasureOverride(大小约束) { callReportInfoEvent(“度量”); 返回base.measureoverride(约束); } 公共事件事件处理程序<infogridEventArgs>reportInfo; private void callReportInfoEvent(字符串消息) { 如果(reportinfo!=空) reportinfo(this,new infogrideventargs(message)); } } 公共类InfoGridEventArgs:EventArgs { 专用信息网格事件参数() { } 公共信息网格事件参数(字符串消息) { this.timestamp=datetime.now; this.message=消息; } 公共日期时间戳 { 得到; 私人集合; } 公共字符串消息 { 得到; 私人集合; } } } < /代码>

    主窗口xaml

    <window x:class=“gridMeasureExample.window1”
    xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation”(http://schemas.microsoft.com/winfx/2006/xaml/presentation)
    xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:local=“clr-namespace:gridMeasureExample”
    title=“sharedSizeGroup”height=“500”width=“500”>
    格栅& GT;
    <grid.columndefinitions>
    <columnDefinition width=“自动”/>
    <columnDefinition width=“*”/>
    </grid.columndefinitions>
    
    <grid.rowdefinitions>
    <rowdefinition height=“*”/>
    <rowdefinition height=“自动”/>
    </grid.rowdefinitions>
    
    <stackpanel grid.column=“0”
    网格=行“0”
    orientation=“水平”
    HorizontalSignment=“左”
    VerticalAlignment=“顶部”
    grid.isSharedSizeScope=“真”>
    
    <stackpanel orientation=“vertical”width=“100”>
    <local:infogride x:name=“grid1”background=“green”showgridlines=“true”>
    <grid.rowdefinitions>
    <rowdefinition height=“15”/>
    <rowDefinition sharedsizegroup=“group1”/>
    <rowdefinition height=“15”/>
    </grid.rowdefinitions>
    <textblock background=“blue”grid.row=“0”text=“row 0”/>
    <textBlock background=“red”grid.row=“1”name=“textBlock1”height=“100”
    text=“绑定relativesource=relativesource self,path=actualheight”/>gt;
    <textBlock background=“blue”grid.row=“2”text=“row 2”/>
    </local:infogride>
    <textBlock text=“绑定路径=实际高度,元素名称=网格1”/>gt;
    </stackpanel>
    
    <stackpanel orientation=“vertical”width=“100”>
    <local:infogride x:name=“grid2”background=“yellow”showgridlines=“true”>
    <grid.rowdefinitions>
    <rowdefinition height=“15”/>
    <rowDefinition sharedsizegroup=“group1”/>
    <rowdefinition height=“15”/>
    </grid.rowdefinitions>
    <textBlock background=“orange”grid.row=“0”text=“row 0”/>
    <textBlock background=“紫色”grid.row=“1”name=“textBlock2”height=“150”
    text=“绑定relativesource=relativesource self,path=actualheight”/>gt;
    <textBlock background=“orange”grid.row=“2”text=“row 2”/>
    </local:infogride>
    <textBlock text=“绑定路径=实际高度,元素名称=网格2”/>gt;
    </stackpanel>
    
    </stackpanel>
    
    <listbox x:name=“lstinfo”
    网格=列“1”
    网格=行“0”
    margin=“10,0,0,0”
    HorizontalSignment=“伸展”
    VerticalAlignment=“拉伸”/>
    
    <uniformgrid grid.column=“0”
    网格=行“1”
    grid.columnspan=“2”列
    列=“2”
    HorizontalSignment=“中心”
    空白=“5”& gt;
    <button x:name=“btnincrease”margin=“4,0”>增加</button>
    <button x:name=“btndecrease”margin=“4,0”>减少</button>
    </uniformgrid>
    
    和/格栅& GT;
    
    &窗/窗;
    < /代码> 
    
    

    main window constructor(only code in code behind)

    公共窗口1() { 初始化组件();。

    btnincrease.click+=(s,e)=>
    {
    lstinfo.items.add(string.format(“0 increase button pressed”,datetime.now.toString(“hh:mm:ss.ffff”));
    textBlock2.高度+=30;
    };
    btndecrease.click+=(s,e)=>
    {
    lstinfo.items.add(string.format(“0 Decrease button pressed”,datetime.now.toString(“hh:mm:ss.ffff”));
    如果(textBlock2.actualHeight>=30)
    textBlock2.高度-=30;
    };
    
    grid1.reportinfo+=(s,e)=>lstinfo.items.add(string.format(“0左网格:1”),e.timestamp.toString(“hh:mm:s s.ffff”),e.message));
    grid2.reportinfo+=(s,e)=>lstinfo.items.add(string.format(“0右网格:1”),e.timestamp.toString(“hh:mm:ss.ffff”),e.message));
    }
    < /代码> <以某种方式被化,和共享化组。

    这个问题是对earlier questionuser D.H.我试图回答。请原谅长度,但它有助于直观地演示问题。

    他最初的问题是,当满足某些条件(调整右侧网格中的文本块的大小)时,为什么具有sharedSizeGroup的两个网格没有调整到相同的高度。我举了他的例子并扩展了它,因为我怀疑它与度量/安排周期有关。

    事实证明,它确实与度量和安排有关。实际上,这与做一个测量。我觉得这至少是一个问题,如果不是一个bug的话,但是我想对行为有一个解释。

    以下是对所发生的情况的快速概述(仅用于演示目的的鲜艳颜色)。

    启动
    两个网格都有三行,每行包含一个文本块。中间一行是sharedsizegroup。中间行的文本绑定到其文本块的实际高度,初始高度属性硬编码为您看到的值。网格下面的数字表示网格的实际高度。请注意,左侧网格的背景色为绿色。

    Startup

    增加右侧文本块
    当右侧网格的大小增加时,您可以看到两个网格由于SharedSizeGroup而调整为新的高度。右边的列反映了网格的度量和排列调用。

    Increased In Size

    减少右侧文本块,但仍大于左侧文本块
    当右侧网格的大小减小,但仍大于左侧硬编码文本块的大小时,您可以看到由于SharedSizeGroup,两个网格再次调整到新高度。右边的列反映了网格的度量和排列调用。

    Decreased to Minimum Size

    减少右侧文本块小于左侧文本块的大小
    当右侧网格的大小减小,小于左侧硬编码文本块的大小时,您可以看到左侧网格没有减小到“合适”的大小,这可以通过在底部看到网格的绿色背景来证明,并且网格的大小是150而不是130

    如果你看右边的信息,你会注意到左边的网格做了排列,但是没有做测量。

    Decreased Past Size


    下面是复制问题的示例代码。

    InfoGrid和InfoGridEventArgs类

    using System.Windows;
    using System.Windows.Controls;
    namespace GridMeasureExample
    {
        class InfoGrid : Grid
        {
            protected override Size ArrangeOverride(Size arrangeSize)
            {
                CallReportInfoEvent("Arrange");
                return base.ArrangeOverride(arrangeSize);
            }
            protected override Size MeasureOverride(Size constraint)
            {
                CallReportInfoEvent("Measure");
                return base.MeasureOverride(constraint);
            }
            public event EventHandler<InfoGridEventArgs> ReportInfo;
            private void CallReportInfoEvent(string message)
            {
                if (ReportInfo != null)
                    ReportInfo(this, new InfoGridEventArgs(message));
            }
        }
        public class InfoGridEventArgs : EventArgs
        {
            private InfoGridEventArgs()
            {
            }
            public InfoGridEventArgs(string message)
            {
                this.TimeStamp = DateTime.Now;
                this.Message = message;
            }
            public DateTime TimeStamp
            {
                get;
                private set;
            }
            public String Message
            {
                get;
                private set;
            }
        }
    }
    

    主窗口XAML

    <Window x:Class="GridMeasureExample.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:GridMeasureExample"
            Title="SharedSizeGroup" Height="500" Width="500">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
    
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <StackPanel Grid.Column="0" 
                        Grid.Row="0"
                        Orientation="Horizontal" 
                        HorizontalAlignment="Left"
                        VerticalAlignment="Top"
                        Grid.IsSharedSizeScope="True">
    
                <StackPanel Orientation="Vertical" Width="100">
                    <local:InfoGrid x:Name="grid1" Background="Green" ShowGridLines="True">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="15" />
                            <RowDefinition SharedSizeGroup="Group1" />
                            <RowDefinition Height="15" />
                        </Grid.RowDefinitions>
                        <TextBlock Background="Blue" Grid.Row="0" Text="Row 0"/>
                        <TextBlock Background="Red" Grid.Row="1" Name="textBlock1" Height="100"
                               Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/>
                        <TextBlock Background="Blue" Grid.Row="2" Text="Row 2" />
                    </local:InfoGrid>
                    <TextBlock Text="{Binding Path=ActualHeight, ElementName=grid1}" />
                </StackPanel>
    
                <StackPanel Orientation="Vertical" Width="100">
                    <local:InfoGrid x:Name="grid2" Background="Yellow" ShowGridLines="True">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="15" />
                            <RowDefinition SharedSizeGroup="Group1" />
                            <RowDefinition Height="15" />
                        </Grid.RowDefinitions>
                        <TextBlock Background="Orange" Grid.Row="0" Text="Row 0" />
                        <TextBlock Background="Purple" Grid.Row="1" Name="textBlock2" Height="150"
                               Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/>
                        <TextBlock Background="Orange" Grid.Row="2" Text="Row 2" />
                    </local:InfoGrid>
                    <TextBlock Text="{Binding Path=ActualHeight, ElementName=grid2}" />
                </StackPanel>
    
            </StackPanel>
    
            <ListBox x:Name="lstInfo"
                     Grid.Column="1"
                     Grid.Row="0"
                     Margin="10,0,0,0"
                     HorizontalAlignment="Stretch"
                     VerticalAlignment="Stretch" />
    
            <UniformGrid Grid.Column="0"
                         Grid.Row="1"
                         Grid.ColumnSpan="2"
                         Columns="2"
                         HorizontalAlignment="Center"
                         Margin="5">
                <Button x:Name="btnIncrease" Margin="4,0">Increase</Button>
                <Button x:Name="btnDecrease" Margin="4,0">Decrease</Button>
            </UniformGrid>
    
        </Grid>
    
    </Window>
    

    主窗口构造函数(仅代码隐藏)

    公共窗口1() { 初始化组件();

        btnIncrease.Click += (s, e) => 
            {
                lstInfo.Items.Add(String.Format("{0} Increase Button Pressed", DateTime.Now.ToString("HH:mm:ss.ffff")));
                textBlock2.Height += 30;
            };
        btnDecrease.Click += (s, e) =>
            {
                lstInfo.Items.Add(String.Format("{0} Decrease Button Pressed", DateTime.Now.ToString("HH:mm:ss.ffff")));
                if (textBlock2.ActualHeight >= 30)
                    textBlock2.Height -= 30;
            };
    
        grid1.ReportInfo += (s, e) => lstInfo.Items.Add(String.Format("{0} Left Grid: {1}", e.TimeStamp.ToString("HH:mm:ss.ffff"), e.Message));
        grid2.ReportInfo += (s, e) => lstInfo.Items.Add(String.Format("{0} Right Grid: {1}", e.TimeStamp.ToString("HH:mm:ss.ffff"), e.Message));
    }