Как установить размер комбинированного списка на максимальную ширину его содержимого? - PullRequest
5 голосов
/ 13 сентября 2011

У меня есть этот ComboBox

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

Можно ли установить размер поля со списком в ширину его самого широкого элемента?

Например, если содержимое:

John Doe
Jane Mary
Josh

Длина будет равна длине Джейн Мэри.

Кроме того, в этом случае ожидается, что содержимое не изменится после инициализации

Ответы [ 4 ]

3 голосов
/ 13 сентября 2011

Что вы можете сделать, так это создать конвертер, который будет возвращать самую длинную длину одного свойства вашего объекта.Вы можете реализовать конвертер так:

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();
    }
}

А затем просто свяжите свойство Width вашего ComboBox, предоставив список в качестве привязки пути, а конвертер - в качестве конвертера значений.

<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

2 голосов
/ 05 декабря 2011

@ ArsenMkrt: cbItem имеет значение null из-за известной проблемы в SL (здесь ссылка: https://connect.microsoft.com/VisualStudio/feedback/details/687691/silverlight-4-5-beta-combobox-itemcontainergenerator-methods-return-null-and-not-a-combboxitem). Следовательно, сейчас это не рабочее решение.

@ YogWiN: обычно элементыполя со списком - это объекты модели (из привязки ItemsSource), а не элементы управления ComboBoxItem, как вы предполагаете в своем ответе. Поэтому вы не можете выполнить итерацию коллекции элементов.

Кроме того, я попытался переопределить метод PrepareContainerForItemOverride в ComboBox, ноэлементы не имеют ширины, пока не отображаются в раскрывающемся списке. Также я попытался переключить панель по умолчанию самостоятельно, но MeasureOverride вызывается только при открытии раскрывающегося списка ...

Итак, насколько я знаю, сегодня,Вы не можете сделать это с помощью элемента управления ComboBox.

2 голосов
/ 13 сентября 2011

Вы можете написать конвертер вот так

 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 }/>

Надеюсь, это поможет

0 голосов
/ 13 сентября 2011

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

Однако это будет устанавливать размер только для раскрывающейся части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...