“无限”大小的“排列”后消失的WPF控件

时间:2016-07-10 22:49:53

标签: c# wpf

我面临一个奇怪的错误,持续了一个月左右。

我的表格看起来像这样:

enter image description here

当我点击保存图片时:

        var g = new Grid();
        var mv = new MyControl();
        g.Children.Add(mv);
        g.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        g.Arrange(new Rect(g.DesiredSize)); 

        var rtb = new RenderTargetBitmap((int)g.ActualWidth, (int)g.ActualHeight,
            96, 96, PixelFormats.Pbgra32);
        rtb.Render(g);

调用Measure()和Arrange()以适当的大小设置网格的大小(从MyControl检索) 表单控件和在RenderTargetBitmap上呈现的用户控件共享没有公共数据。

隐藏的视觉效果存在,并且视图模型数据已正确填充。

执行此代码并再次显示对话框后,它看起来像这样:

enter image description here

两个复选框都消失了。为什么?!

如果我设置网格的大小(代码中为var g),则不会出现此问题

        var g = new Grid()
        {
            Width = 1024,
            Height = 768
        };

2 个答案:

答案 0 :(得分:0)

RowDefinition的默认ColumnDefinitionGrid1*。这意味着无论Grid有多大的空间,都会给出内容。在这种情况下,Grid会要求其父母为其提供最大可用空间。

在您的情况下,因为您的Grid没有视觉父级,所以它不知道应该渲染多大。你需要给它一个明确的宽度/高度。如果您想将MyControl的内容转换为位图,为什么不在没有Grid的情况下执行此操作?

如果您坚持使用网格,并且尺寸是动态的,那么您应该手动指定RowDefinitionsColumnDefinitions。将它们都更改为auto,这会强制Grid将自身调整为内容大小。尺寸。

答案 1 :(得分:0)

正如MSDN info about Measure (Remarks section)所述:

  

Windows Presentation Foundation中的布局定位计算   (WPF)由Measure呼叫和Arrange呼叫组成。在此期间   测量调用,元素通过使用确定其大小要求   availableSize输入。在编配调用期间,元素大小为   最终确定。

     

availableSize可以是从零到无限的任何数字。分子   参与布局应该返回他们需要的最小尺寸   对于给定的availableSize。

     

首次实例化布局时,它始终会收到Measure调用   在安排之前。但是,在第一次布局通过后,它可能会收到   没有措施的安排电话;这可能发生在一个财产   只影响安排改变(如对齐),或当   父母收到没有措施的安排。测量呼叫将   自动使编配电话无效。

     

布局更新发生asynchronously,这样主线程就是   不等待每一个可能的布局变化。通过查询元素   代码隐藏检查属性值可能不会立即反映出来   更改与大小调整或布局交互的属性   特征(例如,Width属性)。

     

可以使用UpdateLayout方法强制进行布局更新。   但是,调用此方法通常是不必要的,并且可能导致不良   性能

因此,请在保存图片按钮中点击g.UpdateLayout

var g = new Grid();
var mv = new MyControl();
g.Children.Add(mv);
g.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
g.Arrange(new Rect(g.DesiredSize));
g.UpdateLayout();

var rtb = new RenderTargetBitmap((int)g.ActualWidth, (int)g.ActualHeight,
    96, 96, PixelFormats.Pbgra32);
rtb.Render(g);