在扩展桌面上克隆表单

时间:2011-09-06 20:51:29

标签: c# multiple-monitors

这是我的情况(抱歉啰嗦,但我发现很难简明扼要地描述):

我们有一个C#应用程序(我们开发),它在一个带有两个监视器的系统上运行。但是,每个监视器都面向不同的用户。也就是说,具有控制权的用户1仅看到监视器A和用户2,其具有“只读”位置仅看到监视器B.到目前为止,我们一直使用克隆显示器,使得A和B显示相同的信息。但是,希望能够在工作流程中的特定实例中向用户1和2显示不同的内容。

这要求桌面有时克隆而其他时间是扩展的情况。不幸的是,这个解决方案对我来说似乎是不可取的,因为当您在桌面模式之间切换时会出现视觉上的情况(屏幕变黑,临时重新定位窗口) - 它基本上不是一个干净的过渡。这就是我正在探索替代方案的原因。

显然,仅克隆的解决方案不起作用,因此离开扩展模式。

扩展模式很容易让我在监视器A和B上显示两种不同的形式,但是我可以做些什么呢?我希望两个监视器显示同样的东西?有没有办法让我在原始文件打开时显示C#System.Windows.Forms.Form的“复制”或“克隆”,这反映了相同的信息?

我忽视了这个问题的另一个解决方案吗?或者“使用DisplaySwitch.exe在显示模式之间切换”方法是否正确?

(假设我们完全控制平台 - 硬件和软件)

3 个答案:

答案 0 :(得分:2)

考虑使用TightVNC之类的远程访问程序。它可以在环回模式下运行,在客户端程序中显示主监视器图像。然后,您必须移动到第二个监视器才能获得克隆。与您最小化和还原的自定义表单一起使用。

答案 1 :(得分:2)

现在说明我有更多时间来阐述我的评论。

不是试图将表单A克隆到表单B中,而是在两者之间设置某种通信层,这样表单A不关心它与之通信的内容,或者显示的数据是相同还是完全不同。 / p>

最简单的方法是将中介挂钩到表单A上的事件中,并在触发这些事件时,将必要的数据发送到表单B进行呈现。

在数据相同的情况下,这可能就像每次表单A更新并在表单B上呈现快照一样简单(就像harvardflu的回答,但将该逻辑放在调解器中),或者你在另一个线程中运行应用程序进程并通过不同的调解器同时更新表单A和表单B(尽管如你所知,这可能是一个重要的重新设计)。

最佳解决方案可能介于两者之间。

答案 2 :(得分:0)

根据您的需要,即必须刷新的频率等,总是可以选择创建表单的位图,并以第二种形式显示该位图。

我个人认为这是一个黑客攻击,使用类似@pdr提议的中介模式肯定是一种更清洁的方法。但如果你需要一个快速(和肮脏)的解决方案,这可能会完成工作。

发布的代码具有原型质量,应予以相应处理。

public partial class MainForm : Form
{
    private bool m_Running;

    public MainForm()
    {
        InitializeComponent();

        DuplicateForm f2 = new DuplicateForm(this.Text);
        f2.Show();

        m_Running = true;
        Thread t = new Thread(new ThreadStart(() =>
            {
                while (m_Running)
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                      Bitmap bm = new Bitmap(Width, Height);
                      // pnl is a Panel with Dock=Fill
                      pnl.DrawToBitmap(bm, new Rectangle(0, 0, Width, Height));
                      f2.SetImage(this, bm);
                     }));

                    Thread.Sleep(500); // or use a timer
                }
            }));

        t.Start();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        m_Running = false;
    }
}

public partial class DuplicateForm : Form
{
    public DuplicateForm(string title)
    {
        InitializeComponent();
        Text = title + " [copy]";
    }

    public void SetImage(Form source, Image img)
    {
        this.Size = source.Size;
        // Picturebox is a PictureBox control with Dock=Fill
        pictureBox1.Image = img;
    }
}