【问题标题】:Custom window chrome designtime support自定义窗口 chrome 设计时支持
【发布时间】:2013-01-29 20:05:08
【问题描述】:

我有自己的自定义控件库项目,该库中的控件之一是类似窗口的 Zune 软件。在我的 WPF 应用程序中,我使用这个自定义窗口控件而不是默认窗口。当我运行我的应用程序时,一切都显示为它应该显示的内容,但问题是在设计时,在 Visual Studio 2012 中它仍然显示默认窗口。我希望能够在设计时拥有相同的 zune 软件风格。有什么方法,我怎样才能做到这一点?

通常我想要实现的目标类似于https://fluent.codeplex.com/,而不是从基类派生窗口,您所要做的就是以这种方式定义窗口

<Fluent:Ribbon>
<Fluent:RibbonTabItem Header="Home">
    <Fluent:RibbonGroupBox Header="Clipboard">
        <Fluent:SplitButton Text="Paste" Icon="Images\Paste.png" LargeIcon="Images\PasteLarge.png">
        ...
     </Fluent:RibbonGroupBox>
     <Fluent:RibbonGroupBox x:Name="Font" ....
</Fluent:RibbonTabItem>
...

【问题讨论】:

    标签: wpf xaml custom-controls


    【解决方案1】:

    你的意思是这样吗?

    这是我自己的自定义代码,但如果您正在寻找更官方的来源,它可能类似于 http://archive.msdn.microsoft.com/WPFShell 库。

    主窗口派生自现有窗口,或者在本例中为NavigationWindow

    namespace Centivus.WPF
    {
        [TemplatePartAttribute(Name = "PART_SearchTextBox", Type = typeof(TextBox))]
        public class SearchableNavigationWindow : NavigationWindow
        {
            ...
    

    通过模板设置样式

    <!-- Custom NavigationWindow UI -->
    <Style x:Key="Win7NavigationWindow" TargetType="{x:Type local:SearchableNavigationWindow}">
        <Setter Property="MinWidth" Value="400"/>
        <Setter Property="glass:GlassEffect.IsEnabled" Value="True" />
        <Setter Property="glass:GlassEffect.Thickness">
            <Setter.Value>
                <Thickness Top="35"/>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
    
                    <DockPanel x:Name="mainDock"  LastChildFill="True" >
                        <!-- The border is used to compute the rendered height with margins.
                                    topBar contents will be displayed on the extended glass frame.-->
    ...
    

    唯一聪明的部分是使用附加属性来应用玻璃,如果您使用自定义镀铬,我会假设您正在做一些非常相似的事情

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Windows.Interop;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Controls;
    using System.Diagnostics;
    
    namespace Centivus.WPF.Glass
    {
        public class GlassEffect
        {
            public static readonly DependencyProperty IsEnabledProperty =
                 DependencyProperty.RegisterAttached("IsEnabled",
                 typeof(Boolean), typeof(GlassEffect),
                 new FrameworkPropertyMetadata(OnIsEnabledChanged));
    
            public static readonly DependencyProperty ThicknessProperty =
                DependencyProperty.RegisterAttached("Thickness",
                typeof(Thickness), typeof(GlassEffect));
    
            public static readonly DependencyProperty GlassBackgroundProperty =
                DependencyProperty.RegisterAttached("GlassBackground",
                typeof(Brush), typeof(GlassEffect));
    
    
            [DebuggerStepThrough]
            public static void SetGlassBackground(DependencyObject element, Brush value)
            {
                element.SetValue(GlassBackgroundProperty, value);
            }
    
            [DebuggerStepThrough]
            public static Brush GetGlassBackground(DependencyObject element)
            {
                return (Brush)element.GetValue(GlassBackgroundProperty);
            }
    
    
            [DebuggerStepThrough]
            public static void SetThickness(DependencyObject element, Thickness value)
            {
                element.SetValue(ThicknessProperty, value);
            }
    
            [DebuggerStepThrough]
            public static Thickness GetThickness(DependencyObject element)
            {
                return (Thickness)element.GetValue(ThicknessProperty);
            }
    
            [DebuggerStepThrough]
            public static void SetIsEnabled(DependencyObject element, Boolean value)
            {
                element.SetValue(IsEnabledProperty, value);
            }
    
            [DebuggerStepThrough]
            public static Boolean GetIsEnabled(DependencyObject element)
            {
                return (Boolean)element.GetValue(IsEnabledProperty);
            }
    
            [DebuggerStepThrough]
            public static void OnIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
            {
                if ((bool)args.NewValue == true)
                {
                    try
                    {
                        Window wnd = (Window)obj;
                        wnd.Activated += new EventHandler(wnd_Activated);
                        wnd.Loaded += new RoutedEventHandler(wnd_Loaded);
                        wnd.Deactivated += new EventHandler(wnd_Deactivated);
                    }
                    catch (Exception)
                    {
                        //Oh well, we tried
                    }
                }
                else
                {
                    try
                    {
                        Window wnd = (Window)obj;
                        wnd.Activated -= new EventHandler(wnd_Activated);
                        wnd.Loaded -= new RoutedEventHandler(wnd_Loaded);
                        wnd.Deactivated -= new EventHandler(wnd_Deactivated);
                    }
                    catch (Exception)
                    {
                    }
                }
            }
    
            [DebuggerStepThrough]
            static void wnd_Deactivated(object sender, EventArgs e)
            {
                ApplyGlass((Window)sender);
            }
    
            [DebuggerStepThrough]
            static void wnd_Activated(object sender, EventArgs e)
            {            
                ApplyGlass((Window)sender);
            }
    
            [DebuggerStepThrough]
            static void wnd_Loaded(object sender, RoutedEventArgs e)
            {            
                ApplyGlass((Window)sender);
            }
    
    
            [DebuggerStepThrough]
            private static void ApplyGlass(Window window)
            {
                try
                {
                    // Obtain the window handle for WPF application
                    IntPtr mainWindowPtr = new WindowInteropHelper(window).Handle;
                    HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
    
                    // Get System Dpi
                    System.Drawing.Graphics desktop = System.Drawing.Graphics.FromHwnd(mainWindowPtr);
                    float DesktopDpiX = desktop.DpiX;
                    float DesktopDpiY = desktop.DpiY;
    
                    // Set Margins
                    GlassEffect.MARGINS margins = new GlassEffect.MARGINS();
                    Thickness thickness = GetThickness(window);//new Thickness();
    
                    // Extend glass frame into client area
                    // Note that the default desktop Dpi is 96dpi. The  margins are
                    // adjusted for the system Dpi.
                    margins.cxLeftWidth = Convert.ToInt32(thickness.Left * (DesktopDpiX / 96) + 0.5);
                    margins.cxRightWidth = Convert.ToInt32(thickness.Right * (DesktopDpiX / 96) + 0.5);
                    margins.cyTopHeight = Convert.ToInt32((thickness.Top * DesktopDpiX / 96) + 0.5);
                    margins.cyBottomHeight = Convert.ToInt32(thickness.Bottom * (DesktopDpiX / 96) + 0.5);
    
                    int hr = GlassEffect.DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
                    //
                    if (hr < 0)
                    {
                        //DwmExtendFrameIntoClientArea Failed      
                        if(window.IsActive)
                            SetGlassBackground(window, SystemColors.GradientActiveCaptionBrush);
                        else
                            SetGlassBackground(window, SystemColors.GradientInactiveCaptionBrush);
                    }
                    else
                    {
                        mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);
                        SetGlassBackground(window, Brushes.Transparent);
                    }
    
    
                }
                // If not Vista, paint background white.
                catch (DllNotFoundException)
                {
                    SetGlassBackground(window, SystemColors.ControlBrush);
                }
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct MARGINS
            {
                public int cxLeftWidth;      // width of left border that retains its size
                public int cxRightWidth;     // width of right border that retains its size
                public int cyTopHeight;      // height of top border that retains its size
                public int cyBottomHeight;   // height of bottom border that retains its size
            };
    
    
            [DllImport("DwmApi.dll")]
            public static extern int DwmExtendFrameIntoClientArea(
                IntPtr hwnd,
                ref MARGINS pMarInset);
        }
    }
    

    http://alski.net/post/2012/01/13/WPF-Wizards-part-2-Glass.aspx 也有更多信息

    【讨论】:

    • 提供的示例链接,我的问题与玻璃效果无关。我也在转发一些本机代码,但我唯一的问题是在 Visual Studio 中显示窗口的方式与我运行应用程序时显示的方式相同。
    • 嗯,这就是我的观点,没有什么聪明的做法,只是造型如果 wimdow。我相信这只是VS2012的一个特性。我不确定 VS2019 是否做过。
    • 对不起,你是说VS2010吗?我从来没有VS2019的标题。我目前正在使用VS 2012。我忘了提到,如果我在与应用程序相同的项目中使用创建该控件并将其用作UserControl,则问题是当该控件位于单独的类库中时。这是不提供设计时支持的时候。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多