2323using System . Windows . Controls . Primitives ;
2424using System . Windows . Data ;
2525using System . Windows . Input ;
26+ using System . Windows . Media ;
2627using System . Windows . Threading ;
2728
2829using ICSharpCode . ILSpy . Themes ;
30+ using ICSharpCode . ILSpyX . TreeView ;
2931
3032using TomsToolbox . Composition ;
3133
@@ -85,7 +87,8 @@ static void InitToolbar(ToolBar toolBar, IExportProvider exportProvider)
8587 }
8688 }
8789
88- static Button CreateToolbarItem ( IExport < ICommand , IToolbarCommandMetadata > commandExport )
90+
91+ static UIElement CreateToolbarItem ( IExport < ICommand , IToolbarCommandMetadata > commandExport )
8992 {
9093 var command = commandExport . Value ;
9194
@@ -108,9 +111,93 @@ static Button CreateToolbarItem(IExport<ICommand, IToolbarCommandMetadata> comma
108111 parameterBinding . ParameterBinding ) ;
109112 }
110113
114+ if ( command is IProvideParameterList parameterList )
115+ {
116+ toolbarItem . Margin = new Thickness ( 2 , 0 , 0 , 0 ) ;
117+
118+ var dropDownPanel = new StackPanel { Orientation = Orientation . Horizontal } ;
119+
120+ var contextMenu = new ContextMenu {
121+ PlacementTarget = dropDownPanel ,
122+ Tag = command
123+ } ;
124+
125+ ContextMenuService . SetPlacement ( toolbarItem , PlacementMode . Bottom ) ;
126+ toolbarItem . ContextMenu = contextMenu ;
127+ toolbarItem . ContextMenuOpening += ( _ , _ ) =>
128+ PrepareParameterList ( contextMenu ) ;
129+
130+ var dropDownToggle = new ToggleButton {
131+ Style = ThemeManager . Current . CreateToolBarToggleButtonStyle ( ) ,
132+ Content = "▾" ,
133+ Padding = new Thickness ( 0 ) ,
134+ MinWidth = 0 ,
135+ Margin = new Thickness ( 0 , 0 , 2 , 0 )
136+ } ;
137+
138+ dropDownToggle . Checked += ( _ , _ ) => {
139+ PrepareParameterList ( contextMenu ) ;
140+ contextMenu . Placement = PlacementMode . Bottom ;
141+ contextMenu . SetCurrentValue ( ContextMenu . IsOpenProperty , true ) ;
142+ } ;
143+
144+ BindingOperations . SetBinding ( dropDownToggle , ToggleButton . IsCheckedProperty ,
145+ new Binding ( nameof ( contextMenu . IsOpen ) ) { Source = contextMenu } ) ;
146+
147+ BindingOperations . SetBinding ( dropDownToggle , IsEnabledProperty ,
148+ new Binding ( nameof ( IsEnabled ) ) { Source = toolbarItem } ) ;
149+
150+ dropDownPanel . Children . Add ( toolbarItem ) ;
151+ dropDownPanel . Children . Add ( dropDownToggle ) ;
152+ return dropDownPanel ;
153+ }
154+
111155 return toolbarItem ;
112156 }
113157
158+ static void PrepareParameterList ( ContextMenu menu )
159+ {
160+ const int maximumParameterListCount = 20 ;
161+
162+ var command = ( ICommand ) menu . Tag ;
163+ var parameterList = ( IProvideParameterList ) command ;
164+
165+ menu . Items . Clear ( ) ;
166+ foreach ( var parameter in parameterList . ParameterList )
167+ {
168+ MenuItem parameterItem = new MenuItem ( ) ;
169+ parameterItem . Command = CommandWrapper . Unwrap ( command ) ;
170+ parameterItem . CommandParameter = parameter ;
171+ parameterItem . CommandTarget = menu . PlacementTarget ;
172+ parameterItem . InputGestureText = " " ;
173+
174+ var headerPresenter = new ContentPresenter { RecognizesAccessKey = false } ;
175+ parameterItem . Header = headerPresenter ;
176+
177+ var header = parameterList . GetParamaterText ( parameter ) ;
178+ switch ( header )
179+ {
180+ case SharpTreeNode node :
181+ headerPresenter . Content = node . NavigationText ;
182+ if ( node . Icon is ImageSource icon )
183+ parameterItem . Icon = new Image {
184+ Width = 16 ,
185+ Height = 16 ,
186+ Source = icon
187+ } ;
188+ break ;
189+
190+ default :
191+ headerPresenter . Content = header ;
192+ break ;
193+ }
194+
195+ menu . Items . Add ( parameterItem ) ;
196+ if ( menu . Items . Count >= maximumParameterListCount )
197+ break ;
198+ }
199+ }
200+
114201 void MainWindow_KeyDown ( object sender , KeyEventArgs e )
115202 {
116203 if ( e . Handled || e . KeyboardDevice . Modifiers != ModifierKeys . Alt || e . Key != Key . System )
0 commit comments