Warm tip: This article is reproduced from serverfault.com, please click

c#-如何在XAML中使WPF组合框具有其最宽元素的宽度?

(c# - How can I make a WPF combo box have the width of its widest element in XAML?)

发布于 2009-06-23 19:02:39

我知道如何在代码中执行此操作,但是可以在XAML中完成吗?

Window1.xaml:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ComboBox Name="ComboBox1" HorizontalAlignment="Left" VerticalAlignment="Top">
            <ComboBoxItem>ComboBoxItem1</ComboBoxItem>
            <ComboBoxItem>ComboBoxItem2</ComboBoxItem>
        </ComboBox>
    </Grid>
</Window>

Window1.xaml.cs:

using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            double width = 0;
            foreach (ComboBoxItem item in ComboBox1.Items)
            {
                item.Measure(new Size(
                    double.PositiveInfinity, double.PositiveInfinity));
                if (item.DesiredSize.Width > width)
                    width = item.DesiredSize.Width;
            }
            ComboBox1.Measure(new Size(
                double.PositiveInfinity, double.PositiveInfinity));
            ComboBox1.Width = ComboBox1.DesiredSize.Width + width;
        }
    }
}
Questioner
Jeno Csupor
Viewed
11
micahtan 2009-06-25 00:02:24

不能在XAML中使用以下任何一种方法:

  • 创建一个隐藏的控件(Alan Hunford的答案)
  • 彻底更改ControlTemplate。即使在这种情况下,也可能需要创建ItemsPresenter的隐藏版本。

原因是我遇到的默认ComboBox ControlTemplates(Aero,Luna等)都将ItemsPresenter嵌套在弹出窗口中。这意味着这些项目的布局将推迟到实际显示它们之前。

一种简单的测试方法是修改默认的ControlTemplate以将最外面的容器(对于Aero和Luna都是网格)的MinWidth绑定到PART_Popup的ActualWidth。单击下拉按钮时,你将能够让ComboBox自动同步其宽度,但之前没有。

因此,除非你可以在布局系统中强制执行“测量”操作(你可以通过添加第二个控件执行此操作),否则我认为这是不可能完成的。

和往常一样,我欢迎一个简短而优雅的解决方案-但在这种情况下,我所看到的仅有代码隐藏或双重控制/ ControlTemplate hacks的能力。