2011-09-06 20 views
6

Oto moja sytuacja (przepraszam za to, że rozwlekły, ale widzę, że to trudne do opisania tego zwięźle):Klonowanie formularz na rozszerzonym pulpicie

Mamy aplikacji C# (czyli rozwijamy), które działa w systemie z dwoma monitorami. Jednak każdy monitor jest skierowany do innego użytkownika. Oznacza to, że użytkownik 1, który ma kontrolę, widzi tylko monitor A i użytkownik 2, który ma pozycję "tylko do odczytu", tylko widzi monitor B. Do tej pory używaliśmy sklonowanego wyświetlacza, takiego, że wyświetlacz A i B te same informacje. Pożądane jest jednak wyświetlanie różnych rzeczy użytkownikom 1 i 2 w określonych przypadkach w przepływie pracy.

Wymaga to sytuacji, w której pulpit jest czasami klonowany, a inne czasy są rozszerzone. Niestety, to rozwiązanie wydaje mi się niepożądane ze względu na to, co dzieje się wizualnie po przełączeniu się między trybami pulpitu (ekran jest czarny, tymczasowa zmiana położenia okien) - zasadniczo nie jest to czyste przejście. Dlatego szukam alternatyw.

Oczywiście rozwiązanie sklonowane nie działa, więc wychodzi z trybu rozszerzonego.

tryb

Rozszerzony łatwo pozwala mi wyświetlać dwa różne formy na monitorach A i B, ale co mogę zrobić dla czasów chcę oba monitory pokazujące samo? Czy istnieje sposób dla mnie, aby pokazać "kopię" lub "klon" C# System.Windows.Forms.Form, gdy oryginał jest otwarty, który odzwierciedla te same informacje?

Czy istnieje inne rozwiązanie tego problemu, z którym się nie zgadzam? Czy też "przełączanie trybów wyświetlania przy użyciu metody DisplaySwitch.exe" jest tak dobre, jak to tylko możliwe?

(zakładamy, mamy pełną kontrolę nad platformą - sprzęt i oprogramowanie)

+1

Co jest złego w korzystaniu z tego samego systemu, który wyświetla różne informacje, ale wyświetla te same informacje? (prawdopodobnie z dobrym wykorzystaniem wzorca Mediator) – pdr

+0

@pdr Nie jestem pewien, ale myślę, że sugerujesz podejście, w którym, w sytuacjach, w których te same informacje muszą być wyświetlane zarówno w A i B, tworzę dwa wystąpienia Form X i wyświetlać po jednym na każdym monitorze? Mediator ułatwiłby wtedy, jak sądzę, obie instancje, na przykład X1 i X2, pozostaną aktualne. Przypuszczam, że głównym powodem, dla którego próbuję uniknąć tego podejścia, jest to, że sugeruje ono dość znaczące ponowne faktoring, ale może być jedyną alternatywą. – Kohanz

Odpowiedz

0

W zależności od potrzeb, czyli jak często należy go odświeżyć itp, zawsze istnieje możliwość tworzenia bitmapy swojej formie, a wyświetlając że bitmapa w drugiej formie.

bym osobiście traktują to jako bit hack, i za pomocą mediatora-wzór jak @pdr proponuje pewnością jest czystsze podejście. Ale może to załatwić sprawę, jeśli potrzebujesz szybkiego (i brudnego) rozwiązania.

Opublikowany kod ma jakość prototypu i powinien być odpowiednio traktowany.

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; 
    } 
} 
+0

Aplikacja zawiera wideo na żywo, więc podczas gdy doceniam sugestię szybkiego hackowania (w pewnym sensie, prosiłem o jedno), to prawdopodobnie nie byłoby dla mnie skuteczne. – Kohanz

+0

Nie, na pewno nie :) – havardhu

2

Rozważmy pomocą programu zdalnego dostępu jak TightVNC. Może pracować w trybie pętli zwrotnej, wyświetlając obraz głównego monitora w programie klienckim. Które następnie trzeba przenieść na drugi monitor, aby uzyskać klon. Wraz z niestandardową formą, którą minimalizujesz i przywracasz.

+0

To jest interesująca opcja. Musiałbym zbadać, jak TightVNC wygląda na rozszerzonym pulpicie (potrzebuję go bez szwu, np. Bez obramowania, aby móc "pełnoekranować" go na drugim monitorze), a także czy mogę go używać bez naruszania GPL. – Kohanz

2

Aby rozwinąć mój komentarz teraz, że mam więcej czasu.

Zamiast próbować klonować Formę A do Formy B, należy utworzyć między nimi warstwę komunikacyjną, tak aby Formularz A nie dbał o to, z czym się komunikuje lub czy wyświetlane dane są takie same lub zupełnie inne.

Najprostszym sposobem, aby to zrobić, aby zaczepić mediatora do wydarzeń na formularzu A oraz, gdy są wywołane te wydarzenia, wysyłać niezbędne dane do formularza B to render.

W przypadku, gdy dane są takie same, może to być tak proste jak zrobienie migawki za każdym razem, gdy formularz A aktualizuje się i renderuje go na formularzu B (podobnie jak odpowiedź Harvardflu, ale umieszczając tę ​​logikę w mediatorze), lub możesz wziąć go tak daleko, jak uruchamianie procesu aplikacji w innym wątku i jednoczesne aktualizowanie Form A i Formy B za pośrednictwem różnych mediatorów (chociaż, jak sugerujesz, prawdopodobnie będzie to poważna reorganizacja).

Jest prawdopodobne, że optymalne rozwiązanie znajduje się gdzieś pośrodku.

+0

Dzięki za opracowanie. Czuję, że "najlepsze" rozwiązanie leży gdzieś w tej przestrzeni. To, ile potrzebuję, aby przyjrzeć się bliżej. Czas na prototyp, chyba :) – Kohanz