动态宽度绑定到自定义组合框中使用的下拉列表(弹出窗口)

时间:2013-06-13 07:38:15

标签: wpf

我正在使用带样式的自定义ComboBox,我想通过coading动态设置Popup的宽度,以便自动调整弹出窗口的宽度

Change this to

this

所以我想动态更改Popup像第二个图像(无论是ComboBox的大小) 我使用的风格如下

<Style x:Key="ComboBoxStyle" TargetType="{x:Type ComboBox}">
        <Setter Property="Foreground" Value="#666666"/>
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="Height" Value="28"/>
        <Setter Property="BorderThickness" Value="1.5"/>
        <Setter Property="Padding" Value="4,3"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid>                            
                        <Popup Margin="1" x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Grid.ColumnSpan="2" Width="{Binding ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}">
                            <Border Name="DropDownBorder" Width="Auto" Height="Auto" BorderThickness="1,0,1,1" CornerRadius="0,0,4,4" BorderBrush="#FFbbbbbb">
                                <Border.Background>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="White" Offset="0" />
                                        <GradientStop Color="#FFE9E9E9" Offset="1" />
                                    </LinearGradientBrush>
                                </Border.Background>
                                <ScrollViewer CanContentScroll="true">
                                    <ItemsPresenter  />
                                </ScrollViewer>
                            </Border>
                        </Popup>                           
                        <ToggleButton Style="{StaticResource cmbToggle}" Grid.ColumnSpan="2" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                        <ContentPresenter HorizontalAlignment="Left" Margin="5,0,0,0" VerticalAlignment="Center" IsHitTestVisible="false" Content="{TemplateBinding SelectionBoxItem}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

<Style x:Key="cmbToggle" TargetType="{x:Type ToggleButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Border Name="cmbBorder" CornerRadius="3" BorderBrush="#FFaaaaaa" BorderThickness="1.5">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="White" Offset="0" />
                                <GradientStop Color="#FFE9E9E9" Offset="1" />
                            </LinearGradientBrush>
                        </Border.Background>
                        <Border BorderBrush="#FFaaaaaa" BorderThickness="1,0,0,0" Width="20" HorizontalAlignment="Right">                                
                            <Polygon Name="pol" Fill="#FF787878" Points="4,9 8,14 12,9" Stroke="#FF787878" StrokeThickness="0" Margin="1 1 0 0">
                            </Polygon>
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True">
                            <Setter Property="CornerRadius" TargetName="cmbBorder" Value="4,4,0,0"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

所以我的想法是动态改变Popup的宽度(Combobox width - togglebutton width = popup width)。我在App.xaml中有写样式 怎么做,请帮帮我。提前谢谢。

3 个答案:

答案 0 :(得分:2)

好的,在您ToggleButton Style中我们可以看到BorderPolygon的{​​{1}}箭头为Width。这是要从Width

中删除的Popup

因此我们可以做类似的事情:

首先将2列添加到Grid ComboBox

中的ControlTemplate
<ControlTemplate TargetType="{x:Type ComboBox}">
  <Grid>
    <!-- New Bit -->
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*" />
      <ColumnDefinition Width="20" />
    </Grid.ColumnDefinitions>
    <!-- End of New Bit -->
    <Popup x:Name="PART_Popup"
            Grid.ColumnSpan="2"
    ...

然后将Width的{​​{1}}更新为

Popup

您的<Popup x:Name="PART_Popup" Grid.ColumnSpan="2" Width="{Binding Path=ColumnDefinitions[0].ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}" ... 已在适当的控件上提及Style,因此不需要其他内容。这应该可以为您提供所需的输出。

答案 1 :(得分:1)

你可以直接使用

 <ComboBox.Resources>
            <Style TargetType="{x:Type Popup}">
                <Setter Property="Width" Value="110"/>
            </Style>
        </ComboBox.Resources>

答案 2 :(得分:0)

使用 Dhaval Patel 解决方案绑定到视图模型属性就可以了。 我在集合发生变化时使用FormattedText计算最大宽度,并在下面绑定它。

<ComboBox.Resources>
            <Style TargetType="{x:Type Popup}">
                <Setter Property="Width" Value="{Binding MaxWidthOfMyCollection"/>
            </Style>
        </ComboBox.Resources>