WPF 多屏开发,为窗体指定显示屏幕

    在开发POS应用过程中,有一个这样的需求:

POS机大都拥有一个主屏一个副屏,主屏用于业务操作,副屏用于向客户展示实时交易数据。这样就有了对窗体显示在哪个窗体有了特定的要求。但是作为一个比较懒惰的程序员,我重来不愿意为这样的事情去做第二次,所以实现一个Window的扩展来实现这样的事情。

    实现构想,通过System.Windows.Forms下Screen类获取屏幕信息,实现Attribute用于标记窗体指定的显示屏幕。

以下是实现代码:

   

using Pharos.POS.Retailing.MultipScreen;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace Pharos.POS.Retailing
{
    public static class MultipScreenManager
    {
        #region Property

        internal static Screen[] AllScreens
        {
            get
            {
                return Screen.AllScreens;
            }
        }

        internal static Screen PrimaryScreen
        {
            get
            {
                return Screen.PrimaryScreen;
            }
        }

        internal static IEnumerable<Screen> MinorScreens
        {
            get
            {
                return Screen.AllScreens.Where(o => o.Primary == false);

            }
        }

        internal static Screen FirstMinorScreen
        {
            get
            {
                return MinorScreens.FirstOrDefault();
            }
        }

        #endregion Property

        #region Method
        public static void ShowInScreen(this System.Windows.Window win)
        {
            SetScreen(win);
            win.Show();
        }
        public static void ShowDialogInScreen(this System.Windows.Window win)
        {
            SetScreen(win);
            win.ShowDialog();
        }

        private static void SetScreen(System.Windows.Window win)
        {
            var attr = win.GetType().GetCustomAttributes(typeof(MultipScreenAttribute), false).FirstOrDefault(o => o is MultipScreenAttribute);
            int index = 0;
            bool ingoreOperation = false;
            WindowStartupLocationInScreen inScreen = WindowStartupLocationInScreen.CenterScreen;
            if (attr != null)
            {
                var temp = (attr as MultipScreenAttribute);
                index = temp.Index;
                inScreen = temp.InScreen;
                ingoreOperation = temp.IngoreMinorScreenError;
            }
            Screen screen = PrimaryScreen;
            if (index == 1 && FirstMinorScreen != null)
            {
                screen = FirstMinorScreen;
            }
            else if (index > 1 && index < MinorScreens.Count())
            {
                screen = MinorScreens.ElementAt(index);
            }
            else if (index > 0 && index >= MinorScreens.Count() && ingoreOperation)
            {
                return;
            }

            switch (inScreen)
            {
                case WindowStartupLocationInScreen.CenterScreen:
                    SetWindowInScreenCenter(win, screen);
                    break;
                case WindowStartupLocationInScreen.Manual:
                    SetWindowInScreenManual(win, screen);
                    break;
            }
        }

        private static void SetWindowInScreenCenter(System.Windows.Window win, Screen screen)
        {
            win.Top = screen.WorkingArea.Y + (screen.WorkingArea.Height - win.Height) / 2;
            win.Left = screen.WorkingArea.X + (screen.WorkingArea.Width - win.Width) / 2;
        }
        private static void SetWindowInScreenManual(System.Windows.Window win, Screen screen)
        {
            win.Top = screen.WorkingArea.Y;
            win.Left = screen.WorkingArea.X;
        }

        #endregion Method
    }
}
using System;

namespace Pharos.POS.Retailing.MultipScreen
{
    [AttributeUsage(AttributeTargets.Class)]
    public class MultipScreenAttribute : Attribute
    {

        public MultipScreenAttribute(ScreenType type = ScreenType.Primary, WindowStartupLocationInScreen inScreen = WindowStartupLocationInScreen.CenterScreen)
            : this((int)type, inScreen)
        {
        }
        public MultipScreenAttribute(int index = 0, WindowStartupLocationInScreen inScreen = WindowStartupLocationInScreen.CenterScreen)
        {
            Index = index;
            InScreen = inScreen;
        }
        /// <summary>
        /// 在窗体初始化显示的位置
        /// </summary>
        public WindowStartupLocationInScreen InScreen { get; private set; }
        /// <summary>
        /// 屏幕索引, 0为主屏,1+为次屏
        /// </summary>
        public int Index { get; private set; }
        /// <summary>
        /// 当任何指定次屏没有找到时,如果该值为TRUE,则忽略这个页面的显示,否则将显示在主屏
        /// </summary>
        public bool IngoreMinorScreenError { get; private set; }
    }
}
namespace Pharos.POS.Retailing.MultipScreen
{
    public enum ScreenType
    {
        /// <summary>
        /// 主屏
        /// </summary>
        Primary = 0,
        /// <summary>
        /// 次屏
        /// </summary>
        Minor = 1,
    }
}
namespace Pharos.POS.Retailing.MultipScreen
{
    public enum WindowStartupLocationInScreen
    {
        Manual = 0,
        CenterScreen = 1,
    }
}

注意: 请不要在window中设置 WindowStartupLocation,这样将导致界面显示异常,设置屏幕的位置可以通过MultipScreenAttribute 标记设置!

时间: 2024-12-08 08:39:16

WPF 多屏开发,为窗体指定显示屏幕的相关文章

WPF一步步开发XMPP IM客户端:入门

[起因&目标] 因为工作原因接触openfire服务端和spark客户端开发2年,主要是基于openfire扩展开发了针对企业用途的服务器插件,还开发了各个平台上的客户端,详情可搜索微信公众号:CVTalk 在开发过程中,发现基于Spark开发Java Swing客户端(公司内部命名CVTalk)比较重,用户体验很难做到和微信客户端看齐,皮肤的开发也比较费力,公司里绝大部分是windows的客户端,而且高清分辨率屏幕的用户越来越多,内存占用过多的问题也解决不了,swing客户端越发力不从心. 于

WPF应用程序开发

WPF应用程序开发 WPF不仅提供了强大的布局功能和窗体渲染功能,在WPF应用程序开发中,还能够实现如Flash一样的动画效果,这就使得在Windows窗体中能够实现Flash动画效果,Microsoft Expression Blend 2提供了动画轴,动画事件处理面板,方便了开发人员在WPF中实现动画效果. 19.3.1  WPF动画事件 WPF可以像Flash一样支持动画开发,与普通的事件不同的是,WPF包括一个动画事件,这个动画事件描述的是当用户执行某个操作时所触发的动画事件.首先需要创

WPF 利用Process.Start()方法启动指定路径下的exe文件并传递参数接收参数

WPF 利用Process.Start()方法启动指定路径下的exe文件并传递参数接收参数 在开发中遇到这样一个需求:WPF程序A启动WPF程序B并且传递参数,WPF程序B接收参数并处理. 如何来实现这样的需求呢,网络上已经有很多的文章描述这个问题,在这里做个记录. 首先通过如下代码启动WPF客户端B: private void ActionStartClientExcute() { var address = "exe位置"; Process process = new Proces

WPF 多点触摸开发[2]:WPF触摸的几个手势的执行顺序

原文:WPF 多点触摸开发[2]:WPF触摸的几个手势的执行顺序 前面我讲了在win7下使用模拟器,进行调试模拟多点触摸,其实际开发中这样也比较麻烦.. 要拿几个鼠标. 所以更多的人会 买个触摸套 套在显示屏上. 这样可支持 2点触摸. 又没有正真触摸屏的昂贵,价格也相对优惠很多. 接下来进入正题 . WPF其实本身对触摸事件就支持. 其中有些高及触屏的操作的手势路由事件. 大大增强了用户体验性. 使得我们能做出类似iphone手机的的触控效果.并使之这些柔和的效果 移植到桌面触摸应用上. 首先

#WPF的3D开发技术基础梳理

原文:#WPF的3D开发技术基础梳理 自学WPF已经有半年有余了,一遍用,一边学.但是一直没有去触摸WPF的3D开发相关技术,因为总觉得在内心是一座大山,觉得自己没有能力去逾越.最近因为一个项目的相关原因,需要用的3D技术,虽然内心没有底只能硬着头皮上了.最后效果还不错. 开发完之后,对WPF的开发小有所感,于是打算写下来,把相关知识梳理下.给正在学习WPF技术伙伴们一点帮助. 能力平平,知识有限,如有错误,还望雅正. 作为微软推广的一门软件开发技术,肯定会遵循一个基本准则:怎么方便怎么来,怎么

wpf控件开发基础

wpf控件开发基础(3) -属性系统(2) http://www.cnblogs.com/Clingingboy/archive/2010/02/01/1661370.html 这个有必要看看

WPF多屏最大化

如果计算机存在多个显示器,这时设置wpf窗口为最大化,窗口只能在主显示器中实现最大化,如果想要实现窗口拉伸至多屏,需要获取所有显示器分辨率之和.这时用到了System.Windows.SystemParameters命名空间. SystemParameters 是一个类,包含多个系统参数值属性.其中VirtualScreenWidth与VirtualScreenHeight可分别获取虚拟屏上的宽高.虚拟屏即是所有监视器边框. C#代码: public MainWindow() { Initial

工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧

原文:工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧 之前一篇<工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)!> 看到很多朋友回复和支持,非常感谢,尤其是一些拍砖的喷油,感谢你们的批评,受益良多. 我第一份工作便是WPF的开发,一直到现在都非常喜欢这门技术,从懵懵懂懂到现在有一些WPF开发资历,也算是经历了一段坎坷的过程.我的朋友看到我写了VS2013的全攻略,他就推荐我写一个WPF篇,我想了下,的确很多朋友初接触WPF的时候难免会

WPF win7+vs2010开发的打印功能,怎么在XP系统上无法打印

在wpf 中打印功能很强大,但最近是在win7上可以但是布置到xp上就不可以了,查了好多资料终于知道怎么回事了原来xp里没有.net framework3.5 安装一个就OK了要先安装4.0. WPF win7+vs2010开发的打印功能,怎么在XP系统上无法打印