Center WPF RibbonWindow Title via XAML Code

给你一囗甜甜゛ 提交于 2019-12-08 06:11:47

问题


i've found some infos on stackoverflow regarding my problem, so I introduced the following xaml code to my window. Now everything is fine, while the wpf window hasn't quick launch icons or contextual tabs active.

Is there a way to center the application title completely via XAML Code. Thats my current one:

        <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>

回答1:


Here's a very naïve way to do it. It comes about from inspecting the visual tree of a RibbonWindow and its concomitant Ribbon. I've been playing with this code for a couple of hours (and no longer) -- it's a bit rough around the edges and I'm not sure it's completely bug free. There's some optimisations to be made and it should be noted that I suck at WPF; there might be better way to do things.

For what it's worth the code is below, but note first:

  • The references to the PART_Icon template are not directly related to your question, but it is related to the aesthetics of the window.

  • The references to IsWin8OrHigher and FindChild are in classes that I'll include at the end. My interest in Windows 8 is that the native ribbon library centres the title text, whereas earlier versions of Windows do not. I'm trying to emulate that here.

  • I have no idea how the RibbonWindow was shipped with Visual Studio 2012 in its current iteration. The rendering on Windows 8 looks pretty miserable. After all this, I'm tempted to overload TitleTemplate with a TextBlock to get rid of the default glow and leave it at that.

  • The RibbonWindow doesn't look very good maximised, customisation or not.

When I started writing this code, this was approximately what I was aiming for:

For comparison, this is how the RibbonWindow renders itself with no customisation:

This is how it renders with TitleTemplate defined to a TextBlock with TextAlignment="Center" but otherwise without any fancy text effects:

With the code below, we get this result:

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;
    }
}



回答2:


That should be working fine. I've just tested it and the title centers as it should.




回答3:


if you want it truly centered, it needs to be:

HorizontalAlignment="Center"


来源:https://stackoverflow.com/questions/7345422/center-wpf-ribbonwindow-title-via-xaml-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!