Ribbon layout

Jan 19, 2009 at 2:01 AM
Edited Jan 20, 2009 at 1:08 AM
I seem to be the only one with this problem. Before i started with Ribbon i had no WPF experience what so ever. Anyway; I can manage to add controls to the ribbon, but i have absolutely no control over where they are placed Are there any layout controls to the ribbon i dont know about? Thanks 4 any help
Coordinator
Jan 19, 2009 at 6:31 PM
Hi CodeHubro,

The layout experience is unique to Ribbon compared to other WPF controls since Ribbon is required to have group collapse behavior as it resizes.  As a convenience, we've included some default layout patterns which will work with our built-in resizing.  You can change all of this, but the problem is that it's fairly complex to do so and will require you to write your own layout panel.  Your panel will need to include the logic for laying out the controls at different sizes depending on the size of the group as the Ribbon collapses.  Unfortunately I don't know of a sample which does this at the moment, but perhaps one of the other developers on this forum has one which they can share.

If there is a specific problem which you're trying to address, please let us know and we'll see if we can offer any advice (or at the very least, we would love to hear where you are encountering issues so that we can try to address the scenario in V1).

Thanks,
Samantha
Jan 20, 2009 at 12:30 AM
Edited Jan 20, 2009 at 6:02 PM

Thanks for the fast reply. Here are some more spesific questions of what i dont understand

Edit (additional query):
Also, what are default sizes for SmallImageSource and LargeImageSource? When i reference an image it gets resized and skewed because it's not the right size. I need the size the ribbon will be using so the images wont be resized by the ribbon

Edit (discovered bug):
It seems that the RibbonComboBox isn't particularly fond of the grid layout method. And why does the RibbonTextbox have roughly 25% of it's left side blank padding?

Here is the main code for this scenario

...
<r:RibbonGroup.ItemsPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
</r:RibbonGroup.ItemsPanel>

<r:RibbonLabel Margin="0, 4, 0, 0" Grid.Column="0" Grid.Row="0">Task name</r:RibbonLabel>
<r:RibbonLabel Margin="0, 4, 0, 0" Grid.Column="0" Grid.Row="1">Deadline</r:RibbonLabel>
<r:RibbonTextBox Margin="0, 0, 0, 0" Width="100" Grid.Column="1" Grid.Row="0" x:Name="tastNameTextbox" />
<r:RibbonComboBox Width="100" Grid.Column="1" Grid.Row="1" x:Name="deadlineTextbox" />
...
Notice that i used margins to get the labels centered. Is there any way to get ribbon to align things automatically?

Coordinator
Jan 21, 2009 at 12:07 AM

Hi CodeHubro,

 

Ok, I think I can help you out with some of this.

 

First, to recreate the layout you find in the Clipboard group, you can use GroupSizeDefinitions to define the different layouts the controls in the group should take by defining the size of each control in the GroupSizeDefinition using ControlSizeDefinitions.  For example, to get the same layout as the Clipboard group (including the evenly space vertical buttons), you would do something like this:

 

<r:RibbonGroup Name="Group2" Command="{StaticResource SampleCommand1}">

<r:RibbonGroup.GroupSizeDefinitions>

<r:RibbonGroupSizeDefinitionCollection>

<r:RibbonGroupSizeDefinition> <!-- This is the initial layout (L,M,M,M)-->

<r:RibbonControlSizeDefinition ImageSize="Large" IsLabelVisible="True"/> <!-- This is a large control -->

<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/> <!-- This is a medium control -->

<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/> <!-- This is a medium control -->

<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="True"/> <!-- This is a medium control -->

</r:RibbonGroupSizeDefinition>

<r:RibbonGroupSizeDefinition> <!-- This is the second layout (L,S,S,S)-->

<r:RibbonControlSizeDefinition ImageSize="Large" IsLabelVisible="True"/> <!-- This is a large control -->

<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="False"/> <!-- This is a small control -->

<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="False"/> <!-- This is a small control -->

<r:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="False"/> <!-- This is a small control -->

</r:RibbonGroupSizeDefinition>

<r:RibbonGroupSizeDefinition IsCollapsed="True"/> <!-- This is the collapsed layout -->

</r:RibbonGroupSizeDefinitionCollection>   

</r:RibbonGroup.GroupSizeDefinitions>

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />               

<r:RibbonButton Command="{StaticResource SampleCommand1}" />              

</r:RibbonGroup>

 

I think the medium-sized buttons are the ones you are asking about as “normal” sized.  If you want your controls to take that size initially, you can set them to do that using the GroupSizeDefinitions like above.  Many of the built-in templates also use medium-sized buttons in certain layouts.  One thing which you may not be aware of is the GroupSizeReductionOrder.  You can set this on the tab to say which order you want your groups to collapse in, and it’s helpful if, for example, you have a lot of groups on your home tab which don’t all fit in the largest layouts, so you want certain ones to be collapsed initially and they’re not doing it by default.  GroupSizeReductionOrder allows you to say “I want this tab to collapse twice first, then this one once, then this one once, then the first one again, etc.”:

 

<r:RibbonTab Label="Home" GroupSizeReductionOrder="Group2,Group2,Group1,Group3,Group2">

 

And you can set GroupSizeReductionOrder so that if you want certain groups to be collapsed and show medium buttons initially, they will do this (as long as the window is the right width).  This Ribbon Feature Walkthrough document might help you with some of the resizing: http://windowsclient.net/wpf/wpf35/wpf-35sp1-ribbon-walkthrough.aspx

 

In order to get a two-line layout, you’ll need to write your own layout panel.  What you’ve got with the grid in the markup you sent is a start, but it won’t be enough to enable the dynamic resizing.  I’m working on trying to get you an example of this.  To break a row of buttons into a group, you can use the RibbonControlGroup, like so:

 

<r:RibbonGroup Name="Group3" Command="{StaticResource SampleCommand1}">

<r:RibbonControlGroup>

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

</r:RibbonControlGroup>

<r:RibbonControlGroup>

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

<r:RibbonButton Command="{StaticResource SampleCommand1}" />

</r:RibbonControlGroup>

</r:RibbonGroup>

 

The RibbonControlGroup doesn’t really work well with the built in resizing at the moment, though, so if you want more than 2 states for that group (initial layout and collapsed), you’ll need to write a custom layout panel.

 

Haha, yes, there will be a Gallery control available in V1, so you won’t have to make one yourself. J

 

I think the default sizes for SmallImageSource and LargeImageSource are 16x16 and 32x32, if I remember correctly.

 

I’m trying to find an example of a custom items panel since I think that will be helpful to you, but it will likely be a few days.  In the meantime, hopefully this will get you headed in the right direction.  Let me know if you have any other questions.

 

Thanks!

Samantha

Jan 21, 2009 at 7:00 AM
Thanks for this incredibly informative post! The imagesource sizes seems to work well now, thanks. I didn't know about that walkthrough - microsoft is not very good at showing developers this stuff :P
I'm walking through it as we speak.

However if you find yourself without anything to do i still have some general wondering...ments... anyway:
The downsizing of ribbonbuttons to imagesize="small" worked well, but is there any way to do this internally from the button? The way i have to do this is not very dynamic in case i need to change something or what not :)
The textbox have some weird default margins to it's left that i cant seem to get rid of - why is this? (I thought maybe it was room for LabelTitle, but i cant find a variable to change)
Coordinator
Jan 21, 2009 at 6:03 PM

Great!  I'm glad I was able to help with some stuff.  I added a link to that walkthrough document to the bottom of the Ribbon Preview wiki page (http://www.codeplex.com/wpf/Wiki/View.aspx?title=WPF%20Ribbon%20Preview) - thanks for pointing that out, I didn't realize that we forgot to put a link there.  There are also some links on that page to hands-on-labs which are really helpful in learning to use Ribbon.

I'm not sure what you mean about downsizing the RibbonButtons to a small image internally... Could you expand on that?  It sounds like you're looking to do something like: <RibbonButton ImageSize="Small"/>.  Is that what you mean?  If so, there is no way to do that.  We only allow you to set image size and label visibility through the Group/ControlSizeDefinitions, otherwise it would be too difficult to get the built-in resizing to work automatically given that the controls may not be in a layout which the resizing recognizes.  Either you have to use the built-in resizing as is, or you have to write your own using Group/ControlSizeDefintions or by adding your own panel.

As for the RibbonTextBox, I think that space is actually room for the LabelTitle and image.  If you hook up RibbonTextBox to a command which includes a SmallImageSource and LabelTitle, you'll see that they fill that space.  However, I tried using a ControlSizeDefintion which sets IsLabelVisible and IsImageVisible to False, and it doesn't seem to get rid of the label or image like it should, so I think this is a bug in the template.  As a workaround, you can retemplate RibbonTextBox using the following Style (just paste it in the resources of your window):

<Style TargetType="{x:Type r:RibbonTextBox}">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type r:RibbonTextBox}">

<StackPanel Orientation="Horizontal">

<!--<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Command.SmallImageSource}" Width="16" Height="16" />

<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Command.LabelTitle}" VerticalContentAlignment="Center" />-->

<Border x:Name="Bd"

BorderThickness="{TemplateBinding BorderThickness}"

BorderBrush="{TemplateBinding BorderBrush}"

Background="{TemplateBinding Background}"

Height="{TemplateBinding Height}"

Width="150"

SnapsToDevicePixels="True">

<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

</Border>

</StackPanel>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

Notice that I've commented out the Image and Label from the original template, which gets rid of the space to the left of the text box.  To adjust the width of the text box, change the Width value in the Border (Bd).

Thanks,
Samantha

Jan 24, 2009 at 9:41 PM
Thanks a billion! That textbox "retemplating" worked perfectly. Buut i can allways conjure up more empty spaces in my knowledge about the ribbon. F.x. I still find it impossible to re-create the font and paragraph groups. Also i was wondering what it takes to create controls for the ribbon. Would it be like creating a normal forms control, just deriving my class from RibbonControl or something? And would the creation of the control take place in XAML or C# code? Thanks
Coordinator
Jan 29, 2009 at 12:23 AM
Hi CodeHubro,

Unfortunately recreating that Font group from Word is not going to be a simple task.  The problem is that a lot of the controls used in those groups (comboboxes and grouped buttons) don't conform naturally to the large, medium, and small control sizes which are common elsewhere on Ribbon.  Therefore, you need to write a custom panel to handle laying out the controls in the different layouts that they take as the group resizes.  To do this, I'd recommend that you take a look at our source code (using Reflector) to see how we do the layout for the standard resizing templates.  If you look at GroupSizeDefinitionCollection, you'll see where we define the built-in templates.  You'd have to make one of these to handle each layout of the Font group, and within that definition you'd want to include the sort of grid layout that you were using in your markup.  Notice that as the Font group decreases in size, the layout changes from 2 rows to 3 rows and the controls move around to different positions.  Your panel will need to account for this by creating a GroupSizeDefinition for each of these layouts.  Unfortunately we don't have any samples at this time to show you how to do this.  If you are able to get this to work, it would be great if you could post a copy on this thread so that other developers can see what you did also.

To create a control for Ribbon, you can take a standard WPF control and subclass it, adding the IRibbonControl interface.  You then need to modify the control to update the values of appropriate properties (like Header or Content) according to the values of the visual properties in the RibbonCommand which is assigned to the control (like LabelTitle and LargeImageSource).  You also need to update the control's template to handle the layout and resizing.  Some of this will be in C# and some will be in XAML - I would recommend that you take a look at our source code and see how we did this with the controls which ship with Ribbon.  You can follow the same patterns to do it for other controls.

Thanks!
Samantha
Feb 4, 2009 at 7:27 AM
Edited Feb 6, 2009 at 6:20 AM
Thx 4 reply I must really say i still think that a controlsizedefinition should be settable from within a control. What about the times the controls are used in a form and not a ribbongroup?
You could do it as simple as this: If a GroupSizeDeffinition is set to a group, it overrides the controlsizedefinitions of it's children.
Also, why must the microsoft ribbon control be so low leveled? In actipro ribbon you have options as simple as this: ShowApplicationOrb = false; RibbonCollapsed = true; RibbonColorLayout = ColorLayout.Blue/Black/Silver/W7 and such. Why can't microsoft ribbon be as simple? :-P I am already guessing that the gallery control will be horribly hard to use, having to setup custom layout panels and itemsources and shit, while it should be as easy as

<r:RibbonGallery MaxItemsShown="10" MinItemsShown="3">
<r:ribbongalleryitem command="..." />
<r:ribbongalleryitem command="..." />
<r:ribbongalleryitem command="..." />
<r:ribbongalleryitem command="..." />
<r:ribbongalleryitem command="..." />
</r:RibbonGallery>

And i hope the row layout will be simpler :P Maybe you could actually dumb it down to something like this

<r:ribboncontrolgroup>...</r:ribboncontrolgroup>
<r:ribboncombobox />
<r:ribbonrowbreak />
<r:ribboncontrolgroup>...</r:ribboncontrolgroup>
<r:ribboncombobox />
<r:ribbonbutton smallimagesource="images/btn.png" text="Hey, i'm a button WITHOUT a friggin command!">
<r:ribbonbutton.ControlSizeDefinition>
<r:controlsizedefinition imagesize="small">
</r:RibbonButton.ControlSizeDefinition>
</r:RibbonButton>

<!-- Maybe even as simple as this -->
<r:ribbonbutton imagesize="small" />

And that code could actually break things up into two autosizing centered beautiful rows with buttons that decided their own size and text <3 simply! xD

Now, if i weren't drunk this post would probably be a little neater, but i hope the questions are valid.
(I wrote this post in html view, so all my caps and linebreaks vanished. I had to go over it and clean up, but i'm lazy so it's not perfect)
Have a good 1
Coordinator
Feb 4, 2009 at 5:49 PM
Hi CodeHubro,

Thanks again for the feedback.  We'll certainly take these suggestions into account while completing V1.  To respond to a few of your concerns:

Ribbon controls are not designed to be used outside of a RibbonGroup.  If you're looking to make a form, you should use the standard versions of the controls.

The Ribbon does in fact have a bunch of high-level properties like you named. We have IsMinimized, IsCollapsed, and IsOpen.  We don't have an option to turn off the ApplicationMenu, since that would be in violation of the Licensing Guidelines (but you can accomplish this through retemplating, though we wouldn't recommend it).  Please keep in mind also that this is still only a CTP and we have not finished adding APIs.  For example, in V1 we will have some skinning APIs which you can use to skin the Ribbon, in addition to the two themes which we ship with now.  If you have other suggestions for high-level properties which could be helpful, please share them.  We're more than happy to consider adding more APIs if developers feel that they will add value to the control.

RibbonGallery will actually be fairly similar to what you suggest, but slightly more complicated only because there are two different menus on the Gallery which you could add items to.  You won't need to write any layout panels, just like you don't need to write any layout panels for the Ribbon in 90% of the cases (Word's complex Font group being one example which falls into the 10% which needs a layout panel).

We did consider adding the control size definition properties to the controls, but this didn't make sense because the controls are supposed to be dynamic, and if you're setting image size and label visibility on the control, it doesn't leave room to resize it as the group collapses unless you want to implement a style with all of the triggers for each control yourself.  Instead, we did all that work in our templates and gave you the option of using a simple way (group/control size defintions) or a more difficult way (writing a panel) to modify the behavior if it's not satisfactory for your scenario.

Again, thanks for the feedback.  If you prefer to use one of the third party Ribbons, we encourage you to do that.  Many of the third party controls are on version 2 or 3 and are further along than our new controls and offer different functionality, which is one of the reasons why we are so appreciative of WPF control vendors because they offer developers choices of different solutions so that you can find what works best for you.  V1 of our controls will work for many developers, but if you're not one of them, we certainly won't feel bad if you decide not to use our control.

Thanks,
Samantha
Feb 4, 2009 at 9:31 PM

I would love to use a 3rd party ribbon, but sadly your CTP is the only free ribboncontrol i can find. I found another free one, but it was fugly to say the least.

I consider myself the average developer, and i must say that decisions that makes sense to you seems far off in my mind, but then most non-microsoft developers' neurons dont run on steriods (compliment/phun)

For instance i think microsoft is being unreasonably close-minded about the whole ribbon GUI. I mean, why have they limited their "revolutionary" new GUI to huge applications that must deal with documents and have tons of commands. If they would burn that license idea and make the office 2007 design more suitable for other kinds of applications (for instance a calculator) the ribbon would quite suddenly, excuse me for this grave understatement, rule the world.

* The ribbon should have an optionable size, like about half the height of the regular ribbon, to work with smaller applications like an instant messenger, that only needs one tab and a few commands. This in particular would make me a happy hubro

* You should implement word 2007's awesome status bar with options of controls and stuff in it, like a slider, button, label or textbox.

* The whole microsoft team should watch star trek

And quite easily put, it should be easy for a developer to re-create an office application without diving into custom code and stuff you need serious brain-ceps to do.

I couldn't come up with any other improvement wishes at this moment but i will post back if i do.

Thanks for your time and help though

PS: Microsoft should release a "Standard Icons for Developers" package which contained toolbar icons for all thinkable commands and stuff. As a developer, photoshopping icons is a nightmare to me.

PS PS: Ribbons Windows 7 theme is fugly. The small cubic application menu button give me chills. It should have the allmighty orb.

Aug 24, 2009 at 9:12 PM

Hey Samantha,

Your posts have been very helpful.  I was able to update the RibbonTextBox style but having an issue changing the RibbonComboBox style, I lose the button.

Can you post what the style for that looks like to recreate the default combobox?  Is there a way for me to know what the default style is so I can see how the controls are built?

Thanks in advance
Tecjda

Sep 28, 2010 at 5:40 PM
samanthamsft wrote:

Great!  I'm glad I was able to help with some stuff.  I added a link to that walkthrough document to the bottom of the Ribbon Preview wiki page (http://www.codeplex.com/wpf/Wiki/View.aspx?title=WPF%20Ribbon%20Preview) - thanks for pointing that out, I didn't realize that we forgot to put a link there.  There are also some links on that page to hands-on-labs which are really helpful in learning to use Ribbon.

I'm not sure what you mean about downsizing the RibbonButtons to a small image internally... Could you expand on that?  It sounds like you're looking to do something like: <RibbonButton ImageSize="Small"/>.  Is that what you mean?  If so, there is no way to do that.  We only allow you to set image size and label visibility through the Group/ControlSizeDefinitions, otherwise it would be too difficult to get the built-in resizing to work automatically given that the controls may not be in a layout which the resizing recognizes.  Either you have to use the built-in resizing as is, or you have to write your own using Group/ControlSizeDefintions or by adding your own panel.

As for the RibbonTextBox, I think that space is actually room for the LabelTitle and image.  If you hook up RibbonTextBox to a command which includes a SmallImageSource and LabelTitle, you'll see that they fill that space.  However, I tried using a ControlSizeDefintion which sets IsLabelVisible and IsImageVisible to False, and it doesn't seem to get rid of the label or image like it should, so I think this is a bug in the template.  As a workaround, you can retemplate RibbonTextBox using the following Style (just paste it in the resources of your window):

<Style TargetType="{x:Type r:RibbonTextBox}">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type r:RibbonTextBox}">

<StackPanel Orientation="Horizontal">

<!--<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Command.SmallImageSource}" Width="16" Height="16" />

<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Command.LabelTitle}" VerticalContentAlignment="Center" />-->

<Border x:Name="Bd"

BorderThickness="{TemplateBinding BorderThickness}"

BorderBrush="{TemplateBinding BorderBrush}"

Background="{TemplateBinding Background}"

Height="{TemplateBinding Height}"

Width="150"

SnapsToDevicePixels="True">

<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

</Border>

</StackPanel>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

Notice that I've commented out the Image and Label from the original template, which gets rid of the space to the left of the text box.  To adjust the width of the text box, change the Width value in the Border (Bd).

Thanks,
Samantha

 I used your code from above for a textbox in my Ribbon application. I am now able to set the width of the textbox - but now I have no label. I uncommented the Label attrribute from your code snippet above, but I still do not get a Label. Any ideas?

Thanks,

Mitch