WPF:内容に合わせて表示幅の変わるコンボボックス
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <ComboBox Name="combobox" HorizontalAlignment="Center" VerticalAlignment="Center"> <ComboBoxItem>aaaa</ComboBoxItem> <ComboBoxItem>aaaa</ComboBoxItem> <ComboBoxItem>aaaa</ComboBoxItem> <ComboBoxItem>aaaazzzzzzzzzzzzzz</ComboBoxItem> <ComboBoxItem>aaaa</ComboBoxItem> </ComboBox> </Grid> </Window>
コードビハインド
/// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); combobox.Loaded += Combobox_Loaded; combobox.Unloaded += Combobox_Unloaded; } private void Combobox_Loaded(object sender, RoutedEventArgs e) { ComboBox combo = sender as ComboBox; App.Current.Dispatcher.BeginInvoke(new Action(() => SetWidth(combo))); } private void Combobox_Unloaded(object sender, RoutedEventArgs e) { ComboBox comboBox = sender as ComboBox; if (comboBox == null) return; combobox.Loaded -= Combobox_Loaded; combobox.Unloaded -= Combobox_Unloaded; } public static void SetWidth(ComboBox combo) { double itemWidth = 0; foreach (var item in combo.Items) { ComboBoxItem comboboxItem = item as ComboBoxItem; if (comboboxItem == null) continue; //コンテンツの対象文字列を取得 //MVVMでItemsSourceにバインドしている場合、Itemsの内容がComboBoxItemではない場合があるので //その場合は表示文字列を取得できるよう修正してください string text = comboboxItem.Content.ToString(); var size = string.IsNullOrEmpty(text) ? new Size(0d, 0d) : Measure(text, combo); if (size.Width > itemWidth) { itemWidth = size.Width; } } var button = FindVisualChild<ToggleButton>(combo); if (button != null) { combo.Width = itemWidth + button.ActualWidth; } } private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is T) return (T)child; var childitem = FindVisualChild<T>(child); if (childitem != null) { return childitem; } } return null; } private static Size Measure(string text, Control control) { var formattedText = new FormattedText( text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(control.FontFamily, control.FontStyle, control.FontWeight, control.FontStretch), control.FontSize, Brushes.Black); return new Size(formattedText.Width, formattedText.Height); } } }
上記コードで、アイテムの文字の長さに合わせてWidthが変わるコンボボックスとなる。