Use ScrollBar in DropDownButton?

2019-09-15 02:57发布

问题:

I want use a scrollbar like ComboBox in my DropDown button, the structure actually is this:

<Controls:DropDownButton Content="Nazioni" Width="120" Margin="0, 0, 20, 0" 
                         ScrollViewer.VerticalScrollBarVisibility="Visible"
                         ScrollViewer.CanContentScroll="True"
                         ItemsSource="{Binding Countries}"
                         ItemTemplate="{StaticResource CombinedTemplate}"/>

but I don't see any ScrollViewer as you can see in the image below:

回答1:

The drop-down of the DropDownButton already contains a ScrollViewer (it is named "SubMenuScrollViewer"), so scrolling through its items is supported out-of-the-box. The thing is, that particular ScrollViewer is styled differently than a default ScrollViewer - assuming we're talking about vertical scrolling, it has two buttons above and below the list, responsible for scrolling up and down respectively, as shown below:

So your best bet is to make that particular ScrollViewer use the default style rather than a custom one. By inspecting the MahApps.Metro source code we can see that the ScrollViewer in question is wired to use a dynamic resource with a key value of {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}. So what you need to do is to supply a default style with that key for that control:

<Controls:DropDownButton (...)>
    <Controls:DropDownButton.Resources>
        <Style x:Key="{ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}"
               TargetType="{x:Type ScrollViewer}"
               BasedOn="{StaticResource {x:Type ScrollViewer}}" />
    </Controls.DropDownButton.Resources>
</Controls.DropDownButton>

This way the ScrollViewer within the drop-down will be styled with a default style shipped with MahApps.Metro.



回答2:

To be certain that scrolling will behave as expected, you cannot rely on WPF to place a ScrollViewer where it should be.

As any content can be place on the dropdown, your best option is to drop a ScrollViewer straight onto the component. This way, you can explicitly name it, and have access to its properties. If you bind your list of countries to the lstContent box, you do away with all the messing.

   <extToolkit:DropDownButton Content="Click Me" Margin="15" >
        <extToolkit:DropDownButton.DropDownContent>
            <ScrollViewer>
                <ListBox Name="lstContent" ItemsSource="{Binding Countries}" ItemTemplate="{StaticResource CombinedTemplate}"/> 
            </ScrollViewer>
        </extToolkit:DropDownButton.DropDownContent>
    </extToolkit:DropDownButton>