如何在WPF中创建Windows 8风格的应用程序栏?

2023-12-24

我打算创建一个 Windows 8 风格的应用程序 (Metro),但发现不支持使用双屏,而这是我的应用程序的需求。

现在我正在将我的应用程序重新设计为 WPF 中的桌面应用程序。 但我仍然喜欢模仿 Windows 8 应用程序中的一些漂亮的设计功能。

设计功能之一是通常在 Windows 8 风格的应用程序中使用的弹出栏:

  • 底部应用程序栏用于命令
  • 顶部导航栏
  • 所有应用程序通用的正确魅力

它们的共同设计是一个临时弹出面板,位于当前窗口布局的顶部。

我的问题是:如何在 WPF 中创建类似的东西?

我可以毫无问题地创建一个带有隐藏底行的主网格,该网格可以显示一些常见的命令按钮。但如果让它飞到我的标准布局之上,而不是挤压它,那就太好了。

我知道可以在当前窗口之上打开一个新窗口,但这会产生糟糕的代码设计并且很难变得好看。我更愿意在同一个窗口中执行此操作。


很酷的问题!事实上我最近刚刚完成了魅力吧..

理想情况下你需要的是类似的东西

<Grid x:Name="LayoutRoot">

 <Grid x:Name="Overlay" Panel.ZIndex="1000" Visibility="Collapsed">
    <!-- This is where your slide out control is going to go -->
  </Grid>

  <!-- Use whatever layout you need -->
  <ContentControl x:Name="MainContent" />

</Grid>

现在,不再挤压内容 - 覆盖网格将位于其顶部,类似于超级按钮栏!全部使用 XAML

如果您对此还有疑问,请给我留言!

编辑;我的 Charm 实现 - 请随意使用以获得灵感!

public class SlidePanel : ContentControl
    {
        static SlidePanel()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SlidePanel), new FrameworkPropertyMetadata(typeof(SlidePanel)));
        }

        public SlidePanel()
        {
            EventManager.RegisterClassHandler(typeof(SlidePanel), SlidePanel.MouseEnterEvent,
                                              new RoutedEventHandler(OnLocalMouseEnter));

            EventManager.RegisterClassHandler(typeof(SlidePanel), SlidePanel.MouseLeaveEvent,
                                              new RoutedEventHandler(OnLocalMouseLeave));
        }

        #region Mouse Handlers

        private static void OnLocalMouseEnter(object sender, RoutedEventArgs e)
        {
            SetExpanded(sender, true);
        }

        private static void OnLocalMouseLeave(object sender, RoutedEventArgs e)
        {
            SetExpanded(sender, false);

        }

        private static void SetExpanded(object sender, bool expanded)
        {
            SlidePanel panel = sender as SlidePanel;

            if (panel != null)
            {
                panel.IsExpanded = expanded;
            }
        }

        #endregion Mouse Handlers

        #region Panel Width

        public double PanelWidth
        {
            get { return (double)GetValue(PanelWidthProperty); }
            set { SetValue(PanelWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PanelWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PanelWidthProperty =
            DependencyProperty.Register("PanelWidth", typeof(double), typeof(SlidePanel), new UIPropertyMetadata(5.0));

        #endregion Panel Width

        #region Closed Width

        public double ClosedWidth
        {
            get { return (double)GetValue(ClosedWidthProperty); }
            set { SetValue(ClosedWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ClosedWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ClosedWidthProperty =
            DependencyProperty.Register("ClosedWidth", typeof(double), typeof(SlidePanel), new UIPropertyMetadata(5.0, new PropertyChangedCallback(OnClosedWidthChange)));

        #endregion Closed Width

        #region Expanded Property

        public bool IsExpanded
        {
            get { return (bool)GetValue(IsExpandedProperty); }
            set { SetValue(IsExpandedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsExpanded.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsExpandedProperty =
            DependencyProperty.Register("IsExpanded", typeof(bool), typeof(SlidePanel), new UIPropertyMetadata(false, new PropertyChangedCallback(OnExpandedChanged)));


        #endregion Expanded Property

        #region Property Changes

        private static void OnExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == e.OldValue)
                return;

            SlidePanel panel = d as SlidePanel;

            if (panel == null)
                return;

            bool newVal = (bool)e.NewValue;

            panel.IsExpanded = newVal;

            bool expanded = (bool)panel.GetValue(IsExpandedProperty);

            Storyboard widthAnimation = AnimationHelper.CreateDoubleAnimation<SlidePanel>(panel, expanded,
                (p, a) =>
                {
                    a.From = (double)p.GetValue(SlidePanel.ClosedWidthProperty);
                    a.To = (double)p.GetValue(SlidePanel.PanelWidthProperty);
                },
                (p, a) =>
                {
                    a.From = (double)p.GetValue(SlidePanel.WidthProperty);
                    a.To = (double)p.GetValue(SlidePanel.ClosedWidthProperty);
                }, new TimeSpan(0, 0, 0, 0, 300), WidthProperty);

            Timeline opacity = AnimationHelper.DoubleAnimation(0.0, 1.0, expanded,
                                                                      new TimeSpan(0, 0, 0, 0, 300), OpacityProperty);

            Storyboard.SetTargetName(opacity, panel.Name);

            Storyboard.SetTargetProperty(opacity, new PropertyPath(OpacityProperty));

            widthAnimation.Children.Add(opacity);

            widthAnimation.Begin(panel);

        }

        private static void OnClosedWidthChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SlidePanel panel = d as SlidePanel;

            if (panel != null)
                panel.Width = (double)e.NewValue;
        }

        #endregion Property Changes
    }

我发现的一个小技巧是在未展开时将不透明度设置为 0,但将宽度设置为 10,这样用户就可以将鼠标放在屏幕一侧,然后它会在一秒钟左右后出现。 。 干杯。

编辑 - 根据要求..AnimationHelper。

  public class AnimationHelper
    {
        public static Timeline DoubleAnimation(double from, double to, bool modifier, TimeSpan duration, DependencyProperty property)
        {
            DoubleAnimation animation = new DoubleAnimation();

            if (modifier)
            {
                animation.From = from;
                animation.To = to;

            }
            else
            {
                animation.To = from;
                animation.From = to;
            }

            animation.Duration = new Duration(duration);

            return animation;
        }

        public static Storyboard CreateDoubleAnimation<T>(T control, bool modifier, double from, double to, TimeSpan duration, DependencyProperty property) where T : Control
        {
            return
             AnimationHelper.CreateDoubleAnimation<T>(control, modifier,
                (p, a) =>
                {
                    a.From = from;
                    a.To = to;
                },
                (p, a) =>
                {
                    a.From = to;
                    a.To = from;
                }, duration, property);
        }

        public static Storyboard CreateDoubleAnimation<T>(T control, bool modifier, Action<T, DoubleAnimation> onTrue, Action<T, DoubleAnimation> onFalse, TimeSpan duration, DependencyProperty property) where T : Control
        {
            if (control == null)
                throw new ArgumentNullException("control");

            DoubleAnimation panelAnimation = new DoubleAnimation();

            if (modifier)
            {
                if (onTrue != null)
                    onTrue.Invoke(control, panelAnimation);

            }
            else
            {
                if (onFalse != null)
                    onFalse.Invoke(control, panelAnimation);
            }


            panelAnimation.Duration = new Duration(duration);

            Storyboard sb = new Storyboard();

            Storyboard.SetTargetName(panelAnimation, control.Name);

            Storyboard.SetTargetProperty(panelAnimation, new PropertyPath(property));

            sb.Children.Add(panelAnimation);

            return sb;
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在WPF中创建Windows 8风格的应用程序栏? 的相关文章

随机推荐

  • 为什么这个程序没有给出预期的输出? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么写入字符串时会出现分段错误 https stackoverflow com questions 164194 why do i get a segmentation fault when wri
  • MySQL:删除所有超过 10 分钟的行

    我的表中有一个时间戳字段 如何删除超过 10 分钟的记录 尝试过这个 DELETE FROM locks WHERE time created lt DATE SUB CURRENT TIME INTERVAL 10 MINUTE 没用 我
  • 翻译到世界坐标

    我有鼠标坐标 mousePos 矩阵视图view 以及透视投影矩阵pMatrix 我将坐标转换为世界坐标 找到逆投影矩阵和逆矩阵视图 然后乘以鼠标的坐标 原点坐标是z 4 终点坐标为z 100 在第一种情况下 我得到坐标mouseDir1
  • 期望数组参数具有设定的长度

    我是 Jest 的新手 所以如果这是一个明显的答案 请原谅我 但在滚动文档后我找不到答案 我有一个函数 funcA 它将不同长度的数组传递给另一个函数 funcB 取决于以下论点funcA收到 我正在尝试测试传递给的数组的长度funcB根据
  • 使用 JsonUtility 序列化 2D 数组

    所以我尝试使用 Unity JSON 实用程序保存一些数据 但遇到了一些麻烦 我有一个世界类 里面有一些参数 如宽度高度等 以及一个 Tiles 的二维数组 它是另一个类 缩小版 public class World SerializeFi
  • 为什么 netstat 没有列出我的套接字的开放端口?

    如果运行此示例 您将看到该端口从未列出netstat 为什么 我该如何做到这一点 include
  • 从 Wordpress 媒体库获取单个特定图像

    我已将图像上传到 Wordpress 媒体库 我知道我可以查看图像 然后获取该特定图像的 URL 然后使用imghtml 标签将其显示在页面上 然而这并没有得到alt title caption and description的图像 The
  • Yarn 中的“应用优先”

    我使用的是 Hadoop 2 9 0 是否可以在 YARN 中提交具有不同优先级的作业 根据一些 JIRA 票证 应用程序优先级似乎现已实施 我尝试使用YarnClient 并设置优先级ApplicationSubmissionContex
  • 是否可以像 LINQ 那样创建 C# 语言修改?

    我已经看了很多Skeet 先生关于如何重新实现 LINQ 的博客 http msmvps com blogs jon skeet archive 2011 02 23 reimplementing linq to objects part
  • 在其他控件上方显示透明加载微调器

    我正在旋转器控件中工作 我希望控件支持透明背景色 当绘制弧线时 中间有一个空白区域 我希望该空间是真正透明的 这样我就可以在其后面放置另一个控件 并且它不会被微调器覆盖 我尝试覆盖 CreateParams void 我还设置了支持透明颜色
  • org.springframework.orm.jpa.EntityManagerHolder 无法转换为 org.springframework.orm.hibernate5.SessionHolder

    我尝试将 Spring 与 Hibernate 5 一起使用 但出现此错误 org springframework orm jpa EntityManagerHolder 无法转换为 org springframework orm hibe
  • 执行 querySelector() 和 querySelectorAll() 操作的纯 Javascript 代码,包括 Shadowroots

    我正在尝试编写一个接受两个参数的方法 当前元素的parentNode之一 其中有许多带有shadowroots的childNodes 第二个参数是该元素的childNodes之一的shadowroots之一内的元素的id父节点参数我尝试使用
  • 在 Gunicorn Worker 之间共享锁

    有没有在gunicorn工作人员之间共享多处理锁的好方法 我正在尝试使用 Flask 编写 json API 一些 API 调用将与管理正在运行的进程的 python 类交互 例如用于视频转换的 ffmpeg 当我将 Web Worker
  • Android,熄屏时获取位置

    我使用带有 fused api 的已启动服务 并直接在其上实现位置侦听器 即使屏幕锁定 位置也会持续更新 但如果屏幕关闭 位置就会停止 那么 有没有什么方法可以确保屏幕关闭时位置保持更新呢 我读了很多其他问题 但我真的不知道我错过了什么 p
  • 在运行时选择方法实现

    我想通过选择从给定集合中调用的方法来配置对象在运行时的行为 考虑这个简单的例子 class Parameter class Conf class Obj public Obj const Conf t t t void f Paramete
  • 如何在 Eclipse Project Explorer 中删除 JAX-WS Web 服务节点?

    对于开发 我使用 Eclipse Helios 在项目资源管理器中我的一个项目中出现了一个新节点 它称为 JAX WS Web 服务 我不在我的项目中使用网络服务 该节点有两个子节点 服务端点接口和Web服务 两者都是空的 我还有其他一些项
  • ng-click 中的 jQuery 传递 html 元素引用

    NOTE 不是上面的重复 上面是访问单击的元素 这个问题是关于访问不同的元素 QUESTION 如何将元素 不是单击的元素 从我的 html 文档传递到 Angular 范围方法ng click 例子 http jsfiddle net L
  • 无法使用 Angular JS 获取选定选项

    致力于使用 Angular JS 获取选择标签的选定选项 当我更改选择标签时 我得到的属性值为 1 2 我需要的是 一 二 我的示例代码是 JS var app angular module myApp app controller myC
  • C#聚合函数定义解释

    Enumerable Aggregate 有 3 个重载版本 我找不到该函数的任何重载版本来匹配中使用的版本官方示例 https msdn microsoft com en us library bb548651 v vs 110 aspx
  • 如何在WPF中创建Windows 8风格的应用程序栏?

    我打算创建一个 Windows 8 风格的应用程序 Metro 但发现不支持使用双屏 而这是我的应用程序的需求 现在我正在将我的应用程序重新设计为 WPF 中的桌面应用程序 但我仍然喜欢模仿 Windows 8 应用程序中的一些漂亮的设计功