Drop-down Button style like Office Print Backstage

Ribbon for WPF Forum

Posted 7 years ago by Detlef Peters - Software Architect, MID GmbH
Version: 11.2.0552
Avatar

Hello,

I'm currently looking for a special button style, as it is used on the Office 2010 Print Backstage for switching Print Options. These controls seem to be PopupButtons, but with a horizontal stacking of their content (Image, Text, Triangle) instead of the vertical stacking that can be seen on the Info tab.

Do you have any styles ready for that, or do I have to override the ribbonControls:PopupButton style ?

 

Best regards,

  D. Peters

Comments (19)

Answer - Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Detlef,

I'm sorry but I don't believe we have any built-in styles for that look at the moment.  So yes, you'd need to make your own.  At least you can reuse some of the brush assets we define for backstage controls though so that colors look correct.


Actipro Software Support

Answer - Posted 7 years ago by Adam Davis
Avatar

I don't know if you still ned help on this or not but this is what I have so far on my office style combobox

	<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
		<Setter Property="SnapsToDevicePixels" Value="true" />
		<Setter Property="OverridesDefaultStyle" Value="true" />
		<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
		<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
		<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
		<Setter Property="MinWidth" Value="120" />
		<Setter Property="MinHeight" Value="20" />
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type ComboBox}">
					<Grid>
						<ToggleButton x:Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="false" ClickMode="Press" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
						<ContentPresenter x:Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"	ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />
						<TextBox x:Name="PART_EditableTextBox" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" />
						<Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False">
							<Border BorderThickness="1" BorderBrush="#FFA7ABB0" Background="White" CornerRadius="3">
								<Grid x:Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
									<Grid.RowDefinitions>
										<RowDefinition Height="*" />
										<RowDefinition Height="Auto" />
									</Grid.RowDefinitions>
									<Border Grid.Row="0" x:Name="DropDownBorder" BorderThickness="0" Background="White" BorderBrush="#FFA7ABB0" />
									<ScrollViewer Margin="2" SnapsToDevicePixels="True">
										<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
									</ScrollViewer>
									<StackPanel Grid.Row="1" >
										<Border BorderThickness="1">
											<StackPanel Orientation="Vertical">
												<ribbon:Separator />
												<ribbon:Menu>
													<ribbon:Button Label="Add Printer" ToolTip="Add Printer" />
													<ribbon:Button Label="Print to File"  ToolTip="Print to File"/>
												</ribbon:Menu>
											</StackPanel>
										</Border>
									</StackPanel>
								</Grid>
							</Border>
						</Popup>
					</Grid>
					<ControlTemplate.Triggers>
						<Trigger Property="HasItems" Value="false">
							<Setter TargetName="DropDownBorder"	Property="MinHeight" Value="95" />
						</Trigger>
						<Trigger Property="IsGrouping" Value="true">
							<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
						</Trigger>
						<Trigger SourceName="Popup" Property="AllowsTransparency" Value="true">
							<Setter TargetName="DropDownBorder"	Property="CornerRadius"	Value="3" />
						</Trigger>
					</ControlTemplate.Triggers>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
	
	<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
		<Setter Property="SnapsToDevicePixels" Value="true" />
		<Setter Property="OverridesDefaultStyle" Value="true" />
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type ComboBoxItem}">
					<Border x:Name="Border" SnapsToDevicePixels="true" BorderThickness="0" Background="Transparent">
						<ContentPresenter />
					</Border>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
	
	<DataTemplate x:Key="PrinterNameItemTemplate">
		<Grid>
			<Border x:Name="border" BorderThickness="1" CornerRadius="3">
				<Border.Style>
					<Style>
						<Style.Triggers>
							<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ComboBoxItem}, Mode=FindAncestor}}" Value="True">
								<Setter Property="Border.BorderBrush" Value="Transparent" />
								<Setter Property="Border.Background" Value="Transparent" />
							</DataTrigger>
						</Style.Triggers>
					</Style>
				</Border.Style>
				<Border x:Name="border2" BorderThickness="1" CornerRadius="3" >
					<StackPanel x:Name="stackPanel" Orientation="Horizontal" Margin="0" VerticalAlignment="Top" UseLayoutRounding="False">
						<StackPanel.ToolTip>
							<ToolTip Width="210">
								<StackPanel Orientation="Vertical">
									<TextBlock FontWeight="SemiBold"><Run Text="Printer Status" /></TextBlock>
									<TextBlock />
									<StackPanel Orientation="Horizontal">
										<TextBlock Margin="5,0,0,0" Text="Status: " />
										<TextBlock Text="{Binding CurrentPrinterStatus}" />
									</StackPanel>
									<StackPanel Orientation="Horizontal">
										<TextBlock Margin="5,0,0,0" Text="Type: " />
										<TextBlock Text="{Binding CurrentPrinterName}" />
									</StackPanel>
									<StackPanel Orientation="Horizontal">
										<TextBlock Margin="5,0,0,0" Text="Where: " />
										<TextBlock Text="{Binding CurrentPrinterPort}" />
									</StackPanel>
									<TextBlock Margin="5,0,0,0" Text="Comment: " />
									<TextBlock />
								</StackPanel>
							</ToolTip>
						</StackPanel.ToolTip>
						<Border SnapsToDevicePixels="true" x:Name="Bdr" BorderThickness="1" CornerRadius="3" Width="34" Height="34">
							<Border.Style>
								<Style>
									<Style.Triggers>
										<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ComboBoxItem}, Mode=FindAncestor}}" Value="True">                                        
											<Setter Property="Border.BorderBrush" Value="{DynamicResource CustomSelectedSolidBorderBrush}" />										
											<Setter Property="Border.Background" Value="{DynamicResource CustomSelectedSolidBackground}" />
										</DataTrigger>									
									</Style.Triggers>
								</Style>
							</Border.Style>
							<Image x:Name="img" Width="32" Height="32" Stretch="Fill" Source="{Binding Icon}" />
						</Border>
						<StackPanel x:Name="stackPanel1" Orientation="Vertical">
							<TextBlock FontFamily="Segoe UI" FontSize="12.5" Text="{Binding CurrentPrinterName}" Margin="8,0,0,0" />
							<TextBlock FontFamily="Segoe UI" FontSize="12.5" Margin="8,0,0,0" Foreground="{Binding CurrentColor}"><Run Text="{Binding CurrentPrinterStatus}"/></TextBlock>
						</StackPanel>
					</StackPanel>
				</Border>
			</Border>
		</Grid>
		<DataTemplate.Triggers>
			<Trigger Property="IsMouseOver" Value="True">
				<Setter Property="Background" TargetName="border" Value="{DynamicResource ToggleButtonMouseOverBackground}"/>
				<Setter Property="BorderBrush" TargetName="border2" Value="White" />
				<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource ToggleButtonMouseOverBorderBrush}"/>
			</Trigger>
		</DataTemplate.Triggers>
	</DataTemplate>

 

Hope it helps you!

Answer - Posted 7 years ago by Detlef Peters - Software Architect, MID GmbH
Avatar

Hi Adam,

thank you for posting your solution. I will keep it in mind for future enhancements :-)

Anyway, I founded my own solution on a control template for the ribbon:PopupButton class. I did so because there are "Combo Boxes" that do not only contain ComboBoxItems - sometimes there are additional commands, too, as in Powerpoint's "Print Format" option dropdown.

There is some extra todo to show the selected value, but this can easily be done by binding the PopupButton's Label and ImageSourceLarge Properties to a CollectionViewSource that is used as the Menu's ItemSource.

Best regards,

  Detlef

Posted 7 years ago by Adam Davis
Avatar

Could you perhaps either post your solution or email it to me. I wouldn't mind viewing it, especially if it is more efficient than my solution. you can email me at adamtdavis@wdwcomputerservices.com

Posted 7 years ago by Adam Davis
Avatar

wrong area sorry.

[Modified 7 years ago]

Posted 7 years ago by Detlef Peters - Software Architect, MID GmbH
Avatar

Hi Adam,

I basically made a copy of the "PopupButtonMenuItemLargeTemplate" from the ActiproXAMLStyles-Source which you can download separately. The latter has a "SubmenuArrow" path from which I removed the "collapsed" Visibility property, and I added a RotateTransform on it so that the arrow points downward (instead of rightward). The outer Grid of the ControlTemplate needs additional Height="41" and Margin="0,2" properties.

Regards,

  Detlef

Posted 7 years ago by Adam Davis
Avatar

Where did you download the ActiproXAMLStyles-Source from?

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

If you have WPF Studio, it is a download link in your account.  Adam, I believe you have WPF Essentials so you could email our support address to ask for the styles.


Actipro Software Support

Posted 7 years ago by Adam Davis
Avatar

Yes I have essentials.

Posted 7 years ago by Adam Davis
Avatar

So you are using a Popup Button Where I used a ComboBox. How are you populating the Popup Button with the Printer info I am using a class and Binding to the ItemsSource="{Binding Source={StaticResource PrinterListData}}". I used an ItemTemplate="{StaticResource PrinterNameItemTemplate}" to display the information basically Icon, info.

Posted 7 years ago by Detlef Peters - Software Architect, MID GmbH
Avatar

We bind to an ItemSource, too. Our source is an "ObservableCollection<Button>", and the buttons of this collection are built from a "System.Printing.LocalPrintServer.GetPrintQueues(...)" query

Posted 7 years ago by Adam Davis
Avatar

ok thats what I'm doing, Question though. Does yours update if you change the default Printer like MS Word does or do you have to restart the app for it to change the newely selected default printer? I've been trying to figure out a way to trigger a type of class refresh when the backstage is opened.

[Modified 7 years ago]

Posted 7 years ago by Adam Davis
Avatar

One more question Detlef if your please.

I'm having trouble updating the Contents of the popup Button to the selected buttons contents from the popup. I'm using a ListBox inside the popupButton which displays my list of printers just fine, but upon slecting a different printer I don't understand how to change the popups contents to reflect the new printer selection. With a Combobox this is handled for you. I'm curious as to how you handled it. Should I use a MenuList instead? My comboBox solution worked fine with the exception of remaining highlighted after you no longer were using it.

This is currently what it looks like:

[Modified 7 years ago]

Posted 7 years ago by Detlef Peters - Software Architect, MID GmbH
Avatar

Hi Adam,

fine work of yours, as far as I can see from the screenshot. How did you manage to overlap the status bar with the backstage, or don't you have no status bar at all? I consired it a known bug of Actipro that the status bar was always visible even with an open backstage.

 

To answer your question: we simply use bindings for the popup button's Label, MenuItemDescription and ImageSourceLarge properties. They are bound to e.g. a "CurrentPrinter" class which is set by selecting an item from the popup menu.

Posted 7 years ago by Adam Davis
Avatar

To get around the status bar issue, I actually host the statusbar on the ribbon. I'm using a dockpanel and applying the ribbon to the top, the statusbar to the bottom, a navigation window left, with a tabs window right filling the rest. This allows the backstage window to overlap the statusbar.

Not entirely mvvm, but it does the job nicely. I also noticed while parts of the Actipro example are mvvm such as hosting controls in a main window, they still use the pagebehind the xaml for lots of code. 

It's basically for me what works not exactly stickling stricly to an MVVM interface. 

By the way thanks for your answer that helps me alot I will create a the same interface and use the binding it makes sense.

Posted 7 years ago by Adam Davis
Avatar

By the way here is what it looks like with statusbar under the backstage.

Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

A quick suggestion on status bars.  If you are on the latest version (2011.2) then you might want to have it styled using our built-in theme for StatusBars that will look good with Ribbon.

<StatusBar Style="{DynamicResource {x:Static themes:SharedResourceKeys.StatusBarStyleKey}}">


Actipro Software Support

Posted 7 years ago by Adam Davis
Avatar

Pulling my hair out here. Detlef anyway I could take a look at your collection structure and xaml binding s for the button. I just can't seem to tie the popup button to the menu/list so that when they select a popup item it changes the button info. Driving me crazy and I'm sure it because Link is so new to me.

Posted 7 years ago by Adam Davis
Avatar

I finally figured it out!

The latest build of this product (v2018.1 build 0675) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.