我想阻止ComboBox根据所选项目的大小调整大小。考虑这个简化的例子:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="300">
<GroupBox Header="Group Header" Margin="5">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ComboBox MinWidth="100" Grid.Column="0" Margin="5" MaxWidth="150"/>
<ComboBox Grid.Column="1" Margin="5" MinWidth="110">
<ComboBoxItem Content="Very loooooooooooooooooooooooooooooooooooooooong text"/>
<ComboBoxItem Content="Normal text"/>
</ComboBox>
</Grid>
</ScrollViewer>
</GroupBox>
</Window>
当您选择第二个ComboBox中的第一个项目时,该ComboBox会展开,以便所选项目的整个内容适合,从左侧隐藏ComboBox
我想做三件事:
有可能吗?
答案 0 :(得分:4)
我再次看了一下这个问题,发现了比以前提出的更简单的解决方案。我们的想法是覆盖ComboBox类的MeasureOverride函数,并提供有限的可用空间,其中width等于ComboBox的MinWidth属性。为此,我们创建了ComboBox派生类:
public class MyComboBox
: ComboBox
{
protected override Size MeasureOverride(Size constraint)
{
return base.MeasureOverride(new Size(MinWidth, constraint.Height));
}
}
然后我们在控件中使用它来代替ComboBox,并将HorizontalContentAlignment设置为Stretch:
<local:MyComboBox Grid.Column="1" Margin="5" MinWidth="110"
HorizontalContentAlignment="Stretch">
<ComboBoxItem Content="Very loooooooooooooooooooooooooooooooooooooooong text"/>
<ComboBoxItem Content="Normal text"/>
</local:MyComboBox>
您可以将第二个ComboBox的MaxWidth属性绑定到剩下的空间(您可以计算它):
<Window x:Class="Example.MainWindow"
xmlns:local="clr-namespace:Example"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="300">
<Window.Resources>
<local:SubstractConverter x:Key="SubstractConverter"/>
</Window.Resources>
<GroupBox Header="Group Header" Margin="5">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
x:Name="ScrollViewer1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ComboBox MinWidth="100" Grid.Column="0" Margin="5" MaxWidth="150"
x:Name="ComboBox1"/>
<ComboBox Grid.Column="1" Margin="5" MinWidth="110">
<ComboBox.MaxWidth>
<MultiBinding Converter="{StaticResource SubstractConverter}">
<Binding ElementName="ScrollViewer1" Path="ActualWidth"/>
<Binding ElementName="ComboBox1" Path="ActualWidth"/>
<Binding ElementName="ComboBox1" Path="Margin.Left"/>
<Binding ElementName="ComboBox1" Path="Margin.Right"/>
<Binding Path="Margin.Left" RelativeSource="{RelativeSource Self}"/>
<Binding Path="Margin.Right" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</ComboBox.MaxWidth>
<ComboBoxItem Content="Very loooooooooooooooooooooooooooooooooooooooong text"/>
<ComboBoxItem Content="Normal text"/>
</ComboBox>
</Grid>
</ScrollViewer>
</GroupBox>
</Window>
我从scrollviewer的ActualWidth中减去第一个组合框的ActualWidth,第二个组合框的边距和边距。为了减少要减去的元素,可以在ComboBox1周围放置一个边框。然后,您将减去border的ActualWidth而不是ComboBox1属性。
此处使用的转换器:
public class SubstractConverter
: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values != null && values.Any())
{
var result = System.Convert.ToDouble(values.First());
var toSubstract = values.Skip(1);
foreach (var number in toSubstract)
{
result -= System.Convert.ToDouble(number);
}
return result;
}
return 0d;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
答案 1 :(得分:0)
我在ScrollViewer中遇到了与ComboBox相同的问题。我不想要水平滚动但只想垂直。但是ComboBox不断调整自己调整所选项目的大小。我使用了aligators的答案,但用ActualWidth替换了MinWidth,这使得CombobBox不会自己调整大小,但是所选项目将始终使用可用空间。
public class FixedWidthComboBox : ComboBox
{
protected override Size MeasureOverride(Size constraint)
{
return base.MeasureOverride(new Size(ActualWidth, constraint.Height));
}
}