Ribbon ApplicationMenu AuxilaryPane Size
How do I change the size of the AuxilaryPane in the WPF Ribbon ApplicationMenu? I have added a recent file list to that area but it is getting truncated. Ideally I'd like the auxilary pane to fill the screen like it does for Word/Excel.
My code:
<r:Ribbon.ApplicationMenu>
<r:RibbonApplicationMenu>
<r:RibbonApplicationMenu.AuxiliaryPaneContent>
&l开发者_开发问答t;StackPanel>
<TextBlock Text="Recent Files" />
<Separator />
<ItemsControl ItemsSource="{Binding RecentFiles}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<r:RibbonApplicationMenuItem Header="{Binding ShortPath}"
Command="{Binding DataContext.OpenRecentFileCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding LongPath}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</r:RibbonApplicationMenu.AuxiliaryPaneContent>
</r:RibbonApplicationMenu>
</r:Ribbon.ApplicationMenu>
Based on the answers in this thread I found it easiest to subclass RibbonApplicationMenu and set Width of the third column to Auto.
public class CustomRibbonApplicationMenu : System.Windows.Controls.Ribbon.RibbonApplicationMenu
{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
System.Windows.DependencyObject obj = this.GetTemplateChild("PART_AuxiliaryPaneContentPresenter");
System.Windows.Controls.ContentPresenter c = obj as System.Windows.Controls.ContentPresenter;
((System.Windows.Controls.Grid)((System.Windows.Controls.Border)c.Parent).Parent).ColumnDefinitions[2].Width = System.Windows.GridLength.Auto;
}
}
Now you just need to change your Ribbon xaml from
<Ribbon.ApplicationMenu>
<RibbonApplicationMenu>
to
<Ribbon.ApplicationMenu>
<ctrl:CustomRibbonApplicationMenu>
If you are looking for a very quick fix to increase the height, you can simply add some useless RibbonApplicationMenuItems to pad out the box (and not have to modify MS source code).
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu>
<ribbon:RibbonApplicationMenu.Items>
<ribbon:RibbonApplicationMenuItem Name="saveSettings" Header="Save Settings" />
<ribbon:RibbonApplicationMenuItem IsEnabled="False"/> <!--USELESS-->
<ribbon:RibbonApplicationMenuItem IsEnabled="False"/> <!--USELESS-->
</ribbon:RibbonApplicationMenu.Items>
<ribbon:RibbonApplicationMenu.AuxiliaryPaneContent >
<StackPanel Orientation="Vertical" >
<GroupBox>
<Label Content="System Settings" />
</GroupBox>
<StackPanel Orientation="Horizontal">
</StackPanel>
</StackPanel>
</ribbon:RibbonApplicationMenu.AuxiliaryPaneContent>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
I've searched a solution for the same problem.
There is no direct property to modify this.
An Example of creating such property can be found at msdn
here's the main solution:
Change the source code of the Ribbon Library. MS has provided the source code of the Ribbon Library: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2bfc3187-74aa-4154-a670-76ef8bc2a0b4
Download the source code and open it, in the MicrosoftRibbonForWPFSourceAndSamples\RibbonControlsLibrary\Microsoft\Windows\Controls\Ribbon\RibbonApplicationMenu.cs, add one Dependency Property:
public double MinMenuHeight
{
get { return (double)GetValue(MinMenuHeightProperty); }
set { SetValue(MinMenuHeightProperty, value); }
}
public static readonly DependencyProperty MinMenuHeightProperty =
DependencyProperty.Register("MinMenuHeight", typeof(double), typeof(RibbonApplicationMenu), new UIPropertyMetadata(0.0));
In the MicrosoftRibbonForWPFSourceAndSamples\RibbonControlsLibrary\Themes\Generic.xaml, line 7519, add the XAML code:
<Border x:Name="PopupBorder" MinHeight="{TemplateBinding MinMenuHeight}" BorderBrush="{Binding RelativeSource={RelativeSource AncestorType={x:Type ribbon:RibbonMenuButton}}, Path=Ribbon.BorderBrush}" Background="{Binding RelativeSource={RelativeSource AncestorType={x:Type ribbon:RibbonMenuButton}}, Path=Ribbon.Background}" BorderThickness="1" CornerRadius="2">
<Grid>
</Grid>
</Border>
Only add the first two rows of the given xaml
This is an old thread, yes, and it has some good ideas, but I wasn't satisfied.
My problem was slightly different in that I needed the ApplicationMenu to expand only enough to fit any control that was placed in the auxiliary pane.
Eventually I dug deep and found a solution I was happy with. It doesn't solve the "fill the screen" problem, but I'm hoping this will help others who land here, looking for a solution to a problem similar to mine. Sorry if it looks like I'm trying to hijack the thread. I don't intend to.
Essentially I solved the fixed width and height problem by changing the ribbon style:
- Open the ribbon assembly in JetBrains DotPeek
- Open Resources/System.Windows.Controls.Ribbon.g.resources/Themes/generic.baml
- Copy the entire resource dictionary into a .xaml file in your project. You may be able to get away with using only a part of it, but I decided to take the whole thing.
At this point you may be asking, "Why not just use VS or Blend or ShowMeTheTemplate instead of DotPeek?" All of these tools failed miserably on the ribbon assembly. Don't know why. They didn't say. One of the problems with using DotPeek is that some of the namespace references will need adjusting, but it's not too difficult, so I won't go into details here.
So, now that you have all the styles and templates, go look for the offending markup.
First, fix the width:
- Look for the grid whose third column definition is a static value of 300. You can search for
<ColumnDefinition Width="300"/>
. There is only one. - Change the
"300"
to"Auto"
.
Then fix the height:
- Look for the definition of
PART_SubmenuPlaceholder
Border. You can search forx:Name="PART_SubmenuPlaceholder"
. It is about 50 lines below the change you did for the width. - That Border binds the Height property to the ActualHeight property of the "MainPaneBorder" control:
Height="{Binding ElementName=MainPaneBorder, Path=ActualHeight}"
. - Remove this Height definition.
Now that you've modified the style, just add this resource dictionary to your xaml and it should apply itself to the ribbon.
When I came across this answer (while searching for an answer to my own, slightly different question), I wasn't too excited about actually modifying Microsoft code.
As a result, I rather preferred to subclass it, and get the hold of the necessary UI element using base.GetTemplateChild
on the relevant "PART_...".
I suppose you can follow a similar approach to achieve what you need.
My example is here.
Hope this helps.
P.S. If you happen to find a way to determine the necessary width of the AuxiliaryPanel, please let me know - I would like to see if that's applicable to the menu's width as well.
You can download the Microsoft Ribbon for WPF Source Code (http://www.microsoft.com/en-us/download/details.aspx?id=11877) and add a DependencyProperty Width/Height to ApplicationMenu or just do it 'quick and dirty' like in my example:
MainWindow.xaml
public partial class MainWindow : RibbonWindow
{
private Size DefaultApplicationMenuSize;
public MainWindow()
{
InitializeComponent();
}
private void RibbonWindow_Loaded(object sender, RoutedEventArgs e)
{
var grid = (myRibbon.ApplicationMenu.Template.FindName("MainPaneBorder", myRibbon.ApplicationMenu) as Border).Parent as Grid;
/* before the first opening of the menu the size is NaN, so you have to measure size and use the DesiredSize */
grid.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
this.DefaultApplicationMenuSize = new Size(grid.ColumnDefinitions[2].Width.Value, grid.DesiredSize.Height);
}
private void RibbonApplicationMenuItem_MouseEnter(object sender, MouseEventArgs e)
{
Button b=new Button();
b.Content = "my epic button";
b.Width = 500;
b.Height = 500;
b.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
SetApplicationMenuSize(b.DesiredSize);
this.ribbonContentPresenter.Content = b;
}
private void RibbonApplicationMenuItem_MouseLeave(object sender, MouseEventArgs e)
{
SetApplicationMenuSize(DefaultApplicationMenuSize);
this.ribbonContentPresenter.Content = null;
}
private void SetApplicationMenuSize(Size size)
{
var grid = (myRibbon.ApplicationMenu.Template.FindName("MainPaneBorder", myRibbon.ApplicationMenu) as Border).Parent as Grid;
/* you can modify the width of the whole menu */
//grid.Width = size.Width;
/* or just the size of RibbonApplicationMenu.AuxiliaryPaneContent */
grid.ColumnDefinitions[2].Width = new GridLength(size.Width);
grid.Height = size.Height;
}
}
MainWindow.xaml.cs
<ribbon:RibbonWindow x:Class="WpfRibbonApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
Title="MainWindow"
x:Name="RibbonWindow"
Width="640" Height="480"
Loaded="RibbonWindow_Loaded">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ribbon:Ribbon x:Name="myRibbon">
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu SmallImageSource="Images\SmallIcon.png">
<ribbon:RibbonApplicationMenuItem Header="Hello _Ribbon"
ImageSource="Images\LargeIcon.png"/>
<ribbon:RibbonApplicationMenuItem Header="HoverTest"
ImageSource="Images\LargeIcon.png"
MouseEnter="RibbonApplicationMenuItem_MouseEnter"
MouseLeave="RibbonApplicationMenuItem_MouseLeave"
StaysOpenOnClick="True" />
<ribbon:RibbonApplicationMenu.FooterPaneContent>
<ribbon:RibbonButton Label="What ever" HorizontalAlignment="Right"/>
</ribbon:RibbonApplicationMenu.FooterPaneContent>
<ribbon:RibbonApplicationMenu.AuxiliaryPaneContent>
<ribbon:RibbonContentPresenter Name="ribbonContentPresenter" />
</ribbon:RibbonApplicationMenu.AuxiliaryPaneContent>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
</ribbon:Ribbon>
</Grid>
</ribbon:RibbonWindow>
have a nice day
精彩评论