首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF中的绑定和布局关系

WPF中的绑定和布局关系
EN

Stack Overflow用户
提问于 2009-04-09 14:37:59
回答 2查看 1.1K关注 0票数 8

在调查我正在处理的应用程序的问题时,我遇到了一个我不太理解的行为。例如,当你有一个带有绑定文本属性的TextBox时,系统似乎比你有一个静态文本多了一次布局过程。

谁能解释一下为什么会出现这种额外的通行证?引擎是否先放置未绑定的控件,然后绑定它,然后再放置它?

为了测试这一点,我构建了这样的测试用例:

我声明了一个继承自TextBox的类(因此我可以覆盖ArrangeOverride):

代码语言:javascript
复制
public class MultiBoundTextBox : TextBox
{
    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        Console.WriteLine("TextBox.Arrange");
        return base.ArrangeOverride(arrangeBounds);
    }
}

然后我在一个窗口中放置了这个文本框的一个实例:

代码语言:javascript
复制
<local:MultiBoundTextBox x:Name="tb">
Some text
</local:MultiBoundTextBox>

并为测试窗口添加了一些代码:

代码语言:javascript
复制
    public Window11()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("Window.Loaded");
    }

    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        Console.WriteLine("Window.Arrange");
        return base.ArrangeOverride(arrangeBounds);
    }

    private void Window_Initialized(object sender, EventArgs e)
    {
        Console.WriteLine("Window.Initialized");
        tb.DataContext = DateTime.Now;
    }

现在,当我运行这个命令时,我得到了这个输出:

代码语言:javascript
复制
Window.Initialized
Window.Arrange
TextBox.Arrange
Window.Arrange
Window.Loaded

但如果我将Text属性更改为像这样绑定:

代码语言:javascript
复制
    <local:MultiBoundTextBox x:Name="tb">
        <Binding Path="Day" Mode="OneWay" />
    </local:MultiBoundTextBox>

我在输出中得到了如下结果:

代码语言:javascript
复制
Window.Initialized
Window.Arrange
TextBox.Arrange
Window.Arrange
TextBox.Arrange
Window.Arrange
Window.Loaded

注意额外的一对TextBox.Arrange和Window.Arrange。为什么需要额外的通行证?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-09-03 09:43:50

引擎是否先放置未绑定的控件,然后绑定它,然后再放置它?

事实可能的确如此- WPF data binding在很大程度上建立在Dependency Properties之上,这实际上会影响WPF布局过程,请参阅Layout Performance Considerations

其值可能导致布局系统初始化的

依赖属性使用公共标志进行标记。AffectsMeasureAffectsArrange提供了有关哪些属性值更改将强制布局系统进行递归更新的有用线索。通常,任何可以影响元素边界框大小的属性都应该将AffectsMeasure标志设置为true。详情请参考Dependency Properties Overview

具体来说,关于您的问题,请参阅Optimizing Performance: Layout and Design的引文

如果发生以下任一操作,将再次调用布局过程:

  • ...
  • When用影响度量或排列通道的元数据标记的依赖项属性值发生更改。

因此,我可以想象,最初的布局过程与稍后更改绑定值的用例没有任何不同,这将解释您正在经历的行为。虽然这可能仍然是优化启动体验的一个错失的机会,但通常的优化警告适用于:没有测量就没有优化-例如,这种假定的冗余(如果在技术上完全可以避免)可能没有可测量的影响,因为窗口/控件尚未显示等。

调试:

要添加到Drews suggestion of a debugging aid上,在.NET Framework3.5中引入了一个与绑定相关的新的专用调试辅助工具,请参阅PresentationTraceSources.TraceLevel - example:

代码语言:javascript
复制
<Window ... xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase">
    <local:MultiBoundTextBox x:Name="tb">
        <Binding Path="Day" Mode="OneWay"
                 diag:PresentationTraceSources.TraceLevel="High"/>
    </local:MultiBoundTextBox>
</Window>

不过,要实现这一点有一些限制,请务必阅读PresentationTraceSources Class中的部分备注。

票数 2
EN

Stack Overflow用户

发布于 2009-09-02 13:29:29

不是直接的答案,但是如果您向绑定添加一个转换器,该转换器除了写出一条消息来显示绑定的求值时间之外,什么也不做,那该怎么办呢?

代码语言:javascript
复制
public sealed class LoggingConverter : IValueConverter
{
    public void Convert(object value, Type targetType,
                        object parameter, CultureInfo culture)
    {
        Console.WriteLine("Binding.Convert");
        return value;
    }

    public void ConvertBack(object value, Type targetType,
                            object parameter, CultureInfo culture)
    {
        Console.WriteLine("Binding.ConvertBack");
        return value;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/734519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档