通过XAML代码中心WPF RibbonWindow标题

时间:2011-09-08 08:46:35

标签: wpf templates xaml ribbon title

我在stackoverflow上发现了一些关于我的问题的信息,所以我在我的窗口中引入了以下xaml代码。 现在一切都很好,而wpf窗口没有快速启动图标或上下文标签激活。

有没有办法通过XAML代码完全集中应用程序标题。 那是我现在的那个:

        <ribbon:Ribbon.TitleTemplate>
            <DataTemplate>
                <TextBlock TextAlignment="Center" HorizontalAlignment="Stretch" Width="{Binding ElementName=Window, Path=ActualWidth}">ApplicationTitle
                    <TextBlock.Effect>
                       <DropShadowEffect ShadowDepth="0" Color="MintCream " BlurRadius="10"   />   
                    </TextBlock.Effect>
                </TextBlock>
            </DataTemplate>           
        </ribbon:Ribbon.TitleTemplate>

3 个答案:

答案 0 :(得分:3)

这是一种非常天真的方式。它来自于检查RibbonWindow及其伴随Ribbon的可视树。我一直在玩这个代码几个小时(不再是) - 它的边缘有点粗糙,我不确定它是完全没有bug的。有一些优化要做,应该注意我吮吸WPF;可能有更好的办法。

下面是代码的价值,但请先注意:

  • PART_Icon模板的引用与您的问题没有直接关系,但它与窗口的美学有关。

  • IsWin8OrHigherFindChild的引用属于我最后会包含的类。我对Windows 8的兴趣在于本机功能区库以标题文本为中心,而早期版本的Windows则没有。我想在这里效仿。

  • 我不知道RibbonWindow如何在当前迭代中附带Visual Studio 2012。 Windows 8上的渲染看起来非常糟糕。在这之后,我很想用TitleTemplate重载TextBlock以摆脱默认的光晕并将其留在那里。

  • RibbonWindow看起来效果不是很好,也不是自定义。

当我开始编写此代码时,这大概就是我的目标:

enter image description here

为了进行比较,这就是RibbonWindow呈现自身而不进行自定义的方式:

enter image description here

这是TitleTemplate使用TextBlock定义TextAlignment="Center"时的呈现方式,但没有任何奇特的文字效果:

enter image description here

使用下面的代码,我们得到了这个结果:

enter image description here

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 :(得分:1)

这应该可以正常工作。我刚刚测试了它,标题中心应该是它应该的。

答案 2 :(得分:0)

如果你想让它真正居中,那就需要:

HorizontalAlignment="Center"