在扩展桌面上克隆表单
本文关键字:表单 扩展 桌面 | 更新日期: 2023-09-27 18:07:40
我的情况是这样的(很抱歉啰嗦,但我发现很难简明扼要地描述这一点):
我们有一个c#应用程序(我们开发的),运行在一个有两个监视器的系统上。但是,每个监视器面对不同的用户。也就是说,具有控制权的用户1只能看到监视器A,具有"只读"位置的用户2只能看到监视器B。到目前为止,我们一直使用克隆显示器,使A和B显示相同的信息。然而,希望能够在工作流的特定实例中向用户1和用户2显示不同的内容。
这需要一种情况,桌面有时是克隆的,其他时间是扩展的。不幸的是,这个解决方案对我来说似乎是不可取的,因为当你在桌面模式之间切换时,在视觉上发生了什么(屏幕变黑,窗口临时重新定位)——这基本上不是一个干净的过渡。这就是为什么我在寻找替代方案。
显然,仅克隆的解决方案是行不通的,所以只能使用扩展模式。
扩展模式很容易让我在监视器A和B上显示两种不同的形式,但我能做些什么,我想让两个监视器显示相同的东西?是否有一种方法可以让我显示c# System.Windows.Forms.Form的"副本"或"克隆",而原始的是打开的,这反映了相同的信息?
这个问题有没有别的解决办法是我忽略了的?或者是"使用DisplaySwitch.exe在显示模式之间切换"方法尽可能好?
(假设我们完全控制了平台——硬件和软件)
考虑使用TightVNC之类的远程访问程序。它可以在环回模式下运行,在客户端程序中显示主监视器图像。然后,您必须移动到第二个显示器以获得克隆。与最小化和恢复的自定义表单一起使用。
现在我有更多的时间来详细说明我的评论。
与其试图将表单A克隆到表单B,不如在两者之间建立某种通信层,这样表单A就不关心它在与什么通信,也不关心显示的数据是相同的还是完全不同的。
要做到这一点,最简单的方法是将中介连接到表单a上的事件,当这些事件被触发时,将必要的数据发送到表单B以呈现它。
在数据相同的情况下,这可以像每次表单a更新时拍摄快照并在表单B上呈现一样简单(很像harvardflu的答案,但将逻辑放在中介中),或者您可以在另一个线程中运行应用程序进程,并通过不同的中介同时更新表单a和表单B(尽管,正如您所建议的,这可能是一个主要的重新设计)。
根据你的需要,也就是它必须刷新的频率等,你总是可以选择创建一个表单的位图,并在第二个表单中显示该位图。
我个人认为这有点像hack,使用像@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;
}
}