這裏是一個非常簡單的方式來做到這一點。它來自檢查RibbonWindow
及其伴隨Ribbon
的視覺樹。我一直在玩這個代碼幾個小時(不再) - 這有點粗糙,我不確定它完全沒有bug。有一些優化,應該指出,我吮吸WPF;有可能有更好的方式來做事情。
對於什麼是值得的代碼如下,但要注意第一:
到PART_Icon
模板引用不直接關係到你的問題,但它關係到窗戶的美觀。
對IsWin8OrHigher
和FindChild
的引用是我將在最後包含的類。我對Windows 8的興趣在於,本地功能區庫集中了標題文本,而Windows的早期版本則沒有。我試圖在這裏效仿。
我不知道RibbonWindow
在當前迭代中是如何隨Visual Studio 2012一起提供的。 Windows 8上的渲染看起來相當悲慘。在所有這些之後,我試圖用TextBlock
來重載TitleTemplate
以擺脫默認發光,並將其留在那裏。
該RibbonWindow
看起來不是很好,最大化,定製或不。
當我開始寫這個代碼,這大約是什麼,我瞄準了:
爲了便於比較,這是RibbonWindow
如何呈現自己沒有定製:
這是它如何與呈現10定義爲一個TextBlock
與TextAlignment="Center"
但除此之外,沒有任何花哨的文字效果:
與下面的代碼中,我們得到這樣的結果:
MainWindow.cs
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
if (Environment.OSVersion.IsWin8OrHigher())
{
SizeChanged += (sender, args) => TitleHack();
Activated += (sender, args) => TitleHack();
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (!Environment.OSVersion.IsWin8OrHigher())
return;
var icon = GetTemplateChild("PART_Icon") as Image;
if (icon == null)
return;
icon.Margin = new Thickness(icon.Margin.Left + 3, icon.Margin.Top + 2,
icon.Margin.Right, icon.Margin.Bottom);
}
private void TitleHack()
{
var ribbonTitlePanel = MyRibbon.FindChild<FrameworkElement>("PART_TitlePanel");
var qatTopHost = MyRibbon.FindChild<FrameworkElement>("QatTopHost");
var titleHost = MyRibbon.FindChild<FrameworkElement>("PART_TitleHost");
var tabGroup = MyRibbon.FindChild<FrameworkElement>("PART_ContextualTabGroupItemsControl");
var qatTopHostLeft = qatTopHost.TransformToAncestor(ribbonTitlePanel).Transform(new Point(0, 0)).X;
var tabGroupLeft = tabGroup.TransformToAncestor(ribbonTitlePanel).Transform(new Point(0, 0)).X;
var width = ribbonTitlePanel.ActualWidth;
if (tabGroup.Visibility == Visibility.Visible)
{
width -= tabGroup.ActualWidth;
width -= tabGroupLeft - qatTopHostLeft;
}
else
{
width -= qatTopHost.ActualWidth;
}
if (ResizeMode != ResizeMode.NoResize && WindowStyle != WindowStyle.None)
width -= 48; // For the min and max buttons
titleHost.Width = width > 0 ? width : Double.NaN;
}
}
OperatingSystemExtensionMethods.cs
public static class OperatingSystemExtensionMethods
{
private static readonly Version Windows8Version = new Version(6, 2);
public static bool IsWin8OrHigher(this OperatingSystem that)
{
if (that.Platform != PlatformID.Win32NT)
return false;
return that.Version.CompareTo(Windows8Version) >= 0;
}
}
DependencyObjectExtensionMethods.cs
public static class DependencyObjectExtensionMethods
{
public static T FindChild<T>(this DependencyObject that, string elementName)
where T : FrameworkElement
{
var childrenCount = VisualTreeHelper.GetChildrenCount(that);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(that, i);
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && elementName == frameworkElement.Name)
return (T) frameworkElement;
if ((frameworkElement = frameworkElement.FindChild<T>(elementName)) != null)
return (T) frameworkElement;
}
return null;
}
}
+1我一直在試圖找出周圍的'RibbonWindow'自帶的可怕默認標題模板的方式。這給了我一個解決方法。但是,我發現使用快速訪問工具欄和上下文選項卡時遇到的問題。 –
查看窗口的可視化樹,標題部分最終處於「DockPanel」內部。據我所知,他們不提供那麼多的佈局功能。 –
根本問題是,功能區使用帶有專有佈局算法的「RibbonTitlePanel」,該算法將標題放在任何上下文選項卡的右側。我想你可以從'RibbonTitlePanel'派生一個類,並提供一個更好的佈局算法,但是要將它鉤到'Ribbon'控件中,需要修改'Ribbon'控件模板,然後獲取該模板的副本似乎是一項艱鉅的任務。 –