【问题标题】:Setting Margin, Width bound to ActualWidth on Controls causes VS2012 Crash在控件上设置边距、宽度绑定到实际宽度会导致 VS2012 崩溃
【发布时间】:2013-08-14 04:28:27
【问题描述】:

我在搞乱DataGrid 标头并发现了一些尴尬的东西。我一直在玩弄它,直到在 XAML 中找到根本原因并构建了一个如何重现的小样本。

我只使用文本框和数据网格对此进行了测试,但我怀疑它也适用于其他控件。当数据网格或文本框的宽度通过ActualWidth 绑定到同级元素时,在数据网格或文本框上设置Margin 属性(我设置Margin="2")将导致我的整个Visual Studio 几乎立即停止响应。

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" SizeToContent="WidthAndHeight">

        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Horizontal" x:Name="panel">
                <TextBlock Text="Text:1" Width="90" />
                <TextBox Width="90" />
            </StackPanel>
            <DataGrid AutoGenerateColumns="False" Width="{Binding ActualWidth, ElementName=panel}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Test" Width="*" />
                    <DataGridTextColumn Header="Test2" Width="*" />
                    <DataGridTextColumn Header="Test3" Width="*" />
                </DataGrid.Columns>
            </DataGrid>
            <TextBox Width="{Binding ActualWidth, ElementName=panel}"  />
        </StackPanel>
</Window>

这是设计预览在停止响应之前的样子。窗口延伸到“无穷大”,直到我怀疑 VS 内存不足。

知道是什么原因造成的吗?

【问题讨论】:

  • 为每个控件尝试HorizontalAlignment="Left"StackPanelDataGridTextBox)。面板宽度为180,其余部分将继承此值。我认为这是StackPanel的一个特点。

标签: .net wpf xaml user-controls actualwidth


【解决方案1】:

尝试为StackPanel设置HorizontalAlignment="Left"(无论哪种对齐方式):

<StackPanel x:Name="panel" Orientation="Horizontal" HorizontalAlignment="Left">
    <TextBlock Text="Text:1" Width="90" />
    <TextBox Width="90" />
</StackPanel>

在面板宽度将为180,而所有其余控件,此值将继承自绑定(DataGridTextBox)。

引用StackPanel MSDN:

StackPanel 中包含的内容的 Horizo​​ntalAlignment 和 VerticalAlignment 的默认值都是拉伸。

由于面板的默认对齐方式@9​​87654328@,该面板设置WidthHeight 继承自父级 - StackPanel,后者也没有显式参数。而在这个面板中,宽度和高度继承自Window

【讨论】:

  • 是的,我相信问题是堆栈面板的默认HorizontalAlignment="Stretch"。当控件获得Margin="2" 时,兄弟元素的ActualWidth 增加,导致控件的宽度增加,我们最终陷入两个控件都试图满足它们的宽度的无限循环。
【解决方案2】:

在 WPF 中,不应同时指定宽度和边距。两者都可用于设置项目的大小。边距相对于它们的对齐位置。

我怀疑正在发生的事情是边距与宽度规范冲突,并导致在呈现设计时引发某种异常。由于库中的实际代码错误,我不久前遇到了一些 DevExpress 网格控件的类似问题,但结果与您描述的非常相似。

我建议将您的代码转换为仅使用边距和对齐方式。有关详细信息,请参阅此链接:

http://wpftutorial.net/LayoutProperties.html

【讨论】:

  • 不应同时指定宽度和边距。 我不相信这是真的。 Margin 指定 ActualWidth 之外的空间,因此这两个属性应该可以一起运行
  • 应该一起操作。但是,根据我的经验,您将花费更多时间来处理控件和大小、边距和对齐方式。学习使用尺寸或边距,然后找到最适合您的,从长远来看会产生更好的结果和更少的麻烦。
猜你喜欢
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 2011-08-17
  • 2019-03-31
相关资源
最近更新 更多