如何将组合框大小设置为其内容的最大宽度?

时间:2011-09-13 09:12:31

标签: .net wpf combobox

我有这个ComboBox

<ComboBox ItemsSource="{Binding Path=Foo.Bars}"/>

我可以将组合框的大小设置为最宽项目的宽度吗?

例如,如果内容是:

John Doe
Jane Mary
Josh

长度等于Jane Mary的长度。

此外,在这种情况下,预计初始化后内容不会改变

4 个答案:

答案 0 :(得分:3)

您可以做的是制作一个转换器,它将返回对象属性的最长长度。您可以像这样实现转换器:

public class LongestListObjectToIntConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is IEnumerable<FooBar>)
        {
            IEnumerable<FooBar> list = (IEnumerable<FooBar>)value;

            return list.Max(bar => bar.FullName.Length);
        }

        // Default value to return
        return 100;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然后简单地通过将列表作为路径绑定并将转换器作为值转换器来绑定ComboBox的Width属性。

<Window.Resources>
    <conv:LongestListObjectToIntConverter x:Key=converter/>
</Windows.Resources>

    ...

<ComboBox ItemsSource="{Binding Path=Foo.Bars}" Width="{Binding Path=Foo.Bars, Converter={StaticResource converter}}"/>

这样,即使您的集合发生更改并且未通知此更改,ComboBox也会根据最长的单词调整大小。

另一个有趣的想法是在Width上进行自我绑定并抓住转换器中的实际组合框然后检查显示的值,我认为这会更好。

此解决方案的优点是不使用代码隐藏,并且可以轻松重用。您可以在此处找到有关ValueConverters的更多信息:http://www.wpftutorial.net/ValueConverters.html

答案 1 :(得分:2)

您可以像这样编写转换器

 public class ComboBoxToMaxItemWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double maxWidth = 0;
        ComboBox cb = (ComboBox)value;
        foreach (var item in cb.Items)
        {
            ComboBoxItem cbItem = (ComboBoxItem)cb.ItemContainerGenerator.ContainerFromItem(item);
            if (cbItem.ActualWidth > maxWidth)
                maxWidth = cbItem.ActualWidth;
        }
        return maxWidth;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

并使用它

<ComboBox ItemsSource="{Binding Path=Foo.Bars}" Width={Binding RelativeSource={RelativeSource Self}, Converter={StaticResource comboBoxToMaxItemWidthConverter }/>

希望这有帮助

答案 2 :(得分:2)

@ArsenMkrt:由于SL中的已知问题,cbItem为空(此处为链接:https://connect.microsoft.com/VisualStudio/feedback/details/687691/silverlight-4-5-beta-combobox-itemcontainergenerator-methods-return-null-and-not-a-combboxitem)。因此,现在这不是一个可行的解决方案。

@YogWiN:通常,组合框的项目是模型对象(来自ItemsSource绑定),而不是你在答案中假设的ComboBoxItem控件。因此,您无法迭代项集合。

此外,我尝试在ComboBox上覆盖PrepareContainerForItemOverride方法,但元素在下拉列表中显示之前没有宽度。此外,我尝试自己切换默认面板,但只在打开下拉列表时调用MeasureOverride ...

据我所知,今天你无法使用ComboBox控件。

答案 3 :(得分:0)

DropDownWidth可用于设置后面代码的宽度。使用以下链接作为参考。

http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.dropdownwidth%28v=VS.100%29.aspx

http://www.codeproject.com/KB/combobox/ComboBoxAutoWidth.aspx

但是,这只会为下拉部分设置大小。