I have this ComboBox
<ComboBox ItemsSource="{Binding Path=Foo.Bars}"/>
Can I set the size of the combobox to the width of its widest item?
For example, if the contents are:
John Doe
Jane Mary
Josh
The length would be equal to the length of Jane Mary.
Also, in this case the contents are not expected to change after initialization
// Set the size of the combobox mybox. Size = new Size(216, 26);
Simple, add font attribute. For eg. ttk. Combobox(root, values=[1, 2, 3, 4, 5], state="readonly", width=1, font="Verdana 12 bold") .
What you can do is make a converter that would return the longest length of one your object property. You can implement the converter like this:
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();
}
}
And then simply bind the Width property of your ComboBox by provinding the list as the Path binding and your converter as a value converter.
<Window.Resources>
<conv:LongestListObjectToIntConverter x:Key=converter/>
</Windows.Resources>
...
<ComboBox ItemsSource="{Binding Path=Foo.Bars}" Width="{Binding Path=Foo.Bars, Converter={StaticResource converter}}"/>
This way, even if your collection changes and this changes are not notified, the ComboBox would resize depending on the longest word.
Another interesting idea would be to make a self binding on Width and grab the actual combobox in the converter to then inspect the displayed value, that would be even better I think.
The advantage of this solution is that uses no code-behind and is easily reusable. You can find more information on ValueConverters here: http://www.wpftutorial.net/ValueConverters.html
You can write converter like this
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();
}
}
And use it
<ComboBox ItemsSource="{Binding Path=Foo.Bars}" Width={Binding RelativeSource={RelativeSource Self}, Converter={StaticResource comboBoxToMaxItemWidthConverter }/>
Hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With