新足迹

 找回密码
 注册

精华好帖回顾

· 烤猪颈肉 (2009-8-14) pal · 我喜爱的几只尼康卡口镜头 (2011-4-17) zzoz
· 全澳E-tag 产品统计大全+NSW toll roads and Fees+昆州Govia E-tag在NSW测试(85楼) (2013-7-13) relaxchair · NSW州政府的Housing Delivery Program规划细节披露及讨论 (2013-3-18) Martin_2F
Advertisement
Advertisement
查看: 1192|回复: 10

问一个wpf问题 [复制链接]

头像被屏蔽

禁止发言

发表于 2011-5-5 21:16 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
因为今天偶然遇到一个奇怪的问题:

建立一个wpf application
加一个custom control,并且给他加个背景颜色red
<UserControl x:Class="WpfApplication2.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             Background="Red"
             designHeight="300" designWidth="300">

</UserControl>

然后在custom control里加这么一个函数
   protected override Size ArrangeOverride(Size arrangeBounds)
        {
            this.Width = arrangeBounds.Width;
            this.Height = arrangeBounds.Height;
            return base.ArrangeOverride(arrangeBounds);
        }

在main window里面直接调用user control.
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:t="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <t:UserControl1></t:UserControl1>
    </Grid>
</Window>
其他代码都是vs.net 自动的。

按照想当然的逻辑,ArrangeOverride传入的是大小,然后user control的大小也应该变化。
而实际上不是,实际上这2行加了,反而无法随窗口变化大小。不加反而可以。
如果把arrangeBounds的width和height输出到一个文本文件里面,
可以发现,如果这2行不加,arrangeBounds的大小是随着窗口大小变化的,
如果加了,反而变成固定的值了。
Advertisement
Advertisement

2010年度奖章获得者

发表于 2011-5-5 22:34 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
ArrangeOverride 是你想要改变默认layout behavior时用的。 这个没问题。

问题是在            this.Width = arrangeBounds.Width; 里的 "this"

"this" 这里是指 UserControl.  而不是具体的visual control inside that usercontrol.

你可以试着比如说把哪行改为。 (比如说根目录是个Grid)
grid.Width = rrangeBounds.Width;

那个应该就可以变了。  wpf 我也是新手,要是没说道点上,就见笑了哈哈。
足迹 Reader is phenomenal. If you never used, you never lived 火速下载

2010年度奖章获得者

发表于 2011-5-5 22:35 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
你什么工作的,整天搞xaml那么爽。 不会是 Ninemsn 啥的吧? 呵呵。
头像被屏蔽

禁止发言

发表于 2011-5-6 09:04 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
呵呵,我今天早上想明白了。你的确没有说准。

我那个width就是user control的,不是user control里面的content control.

这个问题很简单的。它取决于
<Grid>
        <t:UserControl1></t:UserControl1>
    </Grid>
里的那个Grid.

当user control的width 没有赋值,它是NaN。
这个时候Grid就把当前的width/height传进去。
如果user control的width/height有值了,Grid就传那个user control自己的width /height.

如果把Grid换成Canvas或者其他Layout Control,结果就会不一样。

我自己玩的。工作上只用asp.net+sql.
头像被屏蔽

禁止发言

发表于 2011-5-6 12:34 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我到底应不应该在自己的custom control里面设定这个control的width/height呢?

如何能让我这个control可以在Grid里面自动改变大小,但是在canvas里有能够自己给自己按个尺寸?

退役斑竹

发表于 2011-5-6 12:43 |显示全部楼层
此文章由 阿Ka 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 阿Ka 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-5-5 22:35 发表
你什么工作的,整天搞xaml那么爽。 不会是 Ninemsn 啥的吧? 呵呵。


9msn在搞xaml? 做啥?
Advertisement
Advertisement

2010年度奖章获得者

发表于 2011-5-6 19:19 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 linkspeed 于 2011-5-6 12:34 发表
我到底应不应该在自己的custom control里面设定这个control的width/height呢?

如何能让我这个control可以在Grid里面自动改变大小,但是在canvas里有能够自己给自己按个尺寸?

吧尺寸用binding来做, 动态改变,从arrangeBounds得到值后来计算。 或者用ScaleTransform整个tramsform
不知道行不行?
足迹 Reader is phenomenal. If you never used, you never lived 火速下载
头像被屏蔽

禁止发言

发表于 2011-5-8 18:13 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
>从arrangeBounds得到值后来计

如果计算了,在grid里面就无法自动变大小。
如果不计算,在canvas里面就报错。
头像被屏蔽

禁止发言

发表于 2011-5-9 13:40 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我随便找了一个别人写的wpf control
http://wpfsplitbutton.codeplex.com/
果然有这样的问题。
下载下来,把window1.xaml里面的Grid改成Canvas
然后运行。
头像被屏蔽

禁止发言

发表于 2011-5-10 08:56 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
呵呵,老兄,这个问题解决了。

1. 在UserControl和它的canvas之间还有一个border。
所以xaml里面是logic tree, visual tree里面有个border.
我看了wpf源代码才领悟。

2. 不需要给width/height赋值,arrangeoverride返回的就是自己的width/height。

3. UserControl里面,可以调用base的arrangeoverride也可以直接返回一个size。这2种方法的区别就是
base.arrangeoverride最后是调用control.cs的arrangeoverride,这个函数会调用第一个visualchildren的arrangeoverride。那个visualchildren[0]就是border。

而在usercontrol里面, usercontrol.content是canvas.
所以如果只调用content.arrangeoverride(),那么border的width/height=0, 所以看不到东西。

M$ 坑爹呢。。。。。
头像被屏蔽

禁止发言

发表于 2011-5-10 08:57 |显示全部楼层
此文章由 linkspeed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 linkspeed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
canvas在measureoverride时候,如果child control的desiredsize没有值,它会传入infinit. 所以无法保证measureoverride收到的值都是有意义的。
Advertisement
Advertisement

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部