WPF: Child windows , oder MDI?



  • seh grad das es DragMove() fuer usercontrols gar nicht gibt - schoen bloed - das muss man dann selber machen /=

    dynamischen inhalt hast du indem du einfach ein dependency property definierst welchen den inhalt veraendert
    zb du hast ne checkbox die nennst du "x:Name="_title""

    // ClassName : UserControl
    
    public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(ClassName), new UIPropertyMetadata(ClassName.TitleValueChanged));
    public string Title
    {
    	get { return (string)GetValue(TitleProperty); }
    	set { SetValue(TitleProperty, value); }
    }
    private static void TitleValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    	ClassName className = (ClassName)d;
    	className._title.Content = (string)e.NewValue;
    }
    

    dann kannst du aus dem window heraus sowas schreiben

    <control:ClassName Title="Ich bin der Checkbox Titel" />
    


  • ok danke evil, und ist es auch machbar, da sich ein eigenes usercontrol, wie ein fenster ins projekt hinzufüge und darin jeweils andere elemente mit XAML hinzufüge. So als wenn ich ein Fenster im projekt hinzufüge und diese je nach bedarf designe.



  • war das ne frage?

    moeglich ist das schon - wenn du einmal drag&drop fertig ausprogrammiert hast, und rahmen gezeichnet, hast du doch ne wunderschoene vorlage
    du musst elemente die du selber aus dem Window heraus aendern willst als DependencyProperty implementieren wie in meinem beispiel zu sehen - sonst kannst du das UserControl normal designen wie du es mit einem window machen wuerdest



  • D.h. ich will ein neues Child- Fenster (Mein usercontrol) hinzufügen, dann soll in XAML sowas wie

    <UserControl x:Class="MyShapeControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    
        Title="dummy" Height="300" Width="407">
    
       <Grid>
       </Grid>
    </UserControl>
    

    so das jedes neue UserControl das ich einfüge dynmaisch mit control via XAML oder auch code desingen kann.

    Kann mir das noch nich richtig zusammenreihen wie ich das machen soll.. tutorials, hab ich auch durchforstet aber da ist viel überladen oder nich daswas ich möchste.



  • ich versteh nicht ganz dein problem - das user control kannst du doch designen wie ein ganz normales window - wo ist das problem?

    // main window

    <Window x:Class="MDI_Test.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MDI_Test.Controls"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <controls:SubWindow />
        </Grid>
    </Window>
    

    // control

    <UserControl x:Class="MDI_Test.Controls.SubWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="100" Width="100">
        <Grid>
            <Border BorderThickness="2" BorderBrush="Black">
                <TextBlock Text="Ich bin ein Eigenes control" />
            </Border>
        </Grid>
    </UserControl>
    


  • in deinem Beispiel:

    <Window x:Class="MDI_Test.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MDI_Test.Controls"
        Title="Window1" Height="300" Width="300">
        <Grid>
    <controls:SubWindow x:Name="Fenster"> 
    < Button>Hello</Button> //Button soll im client Bereich des Fenster gezeichnet werden
    </controls:SubWindow>
    
        </Grid>
    </Window>
    

    Dabei soll, das fenster immer eine Titelleiste + button enthalten (siehe nächste code), wenn ich es dann im Fenster wie Oben einbinde, und ich da bspw. ein Button hinzufüge, diese im clientbereich angezeigt werden.

    Hier:

    <UserControl x:Class="MDI_Test.Subwindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MDI_Test.Controls"
        Title="Window1" Height="300" Width="300">
    <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="20"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
    
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" FlowDirection="RightToLeft" Orientation="Horizontal">
                <Button>A</Button>
                <Button>B</Button>
                <Button>C</Button>
            </StackPanel>
    
            <Canvas Grid.Row="1">
                //SOLL CLIENTBEREICH SEIN
            </Canvas>
    
        </Grid>
    </UserControl>
    

    EDIT: Hat evtl. der ContentPresenter was damit zu tun?



  • weiss nicht ob ich dich ganz verstehe #gg
    die Default Content Property (oder wie das heisst) bei nem UserControl ist bereits das MainGrid

    du du bindest das UserControl in dem mainwidow ein, und designst das UserControl aus dem Main Window heraus

    zb - ein SubWindow welches nur einen Border hat:

    <UserControl x:Class="MDI_Test.Controls.SubWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="100" Width="100">
        <Grid>
            <Border BorderThickness="2" BorderBrush="Black" />
        </Grid>
    </UserControl>
    

    das binde ich ein in dem hauptfenster:

    <Window x:Class="MDI_Test.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MDI_Test.Controls"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <controls:SubWindow />
        </Grid>
    </Window>
    

    nun soll es aus dem hauptfenster heraus designed werden, also ein stackpanel mit nem button innerhalb des border

    <Window x:Class="MDI_Test.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MDI_Test.Controls"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <controls:SubWindow>
                <StackPanel>
                    <Button Content="SubButton" />
                </StackPanel>
            </controls:SubWindow>
        </Grid>
    </Window>
    

    hintergrund dabei: intern wird alles was man in dem mainwindow als content eintraegt dem grid angehangen

    <UserControl x:Class="MDI_Test.Controls.SubWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="100" Width="100">
        <Grid>
            <Border BorderThickness="2" BorderBrush="Black" />
            <!-- Inhalt des hauptfensters wird hier eingetragen (StackPanel:Button) -->
        </Grid>
    </UserControl>
    


  • Ja das meine ich, wenn ich es so machen wie du, wird aber der Border aus denm Usercontrol von dem Subbotton übermalt, aber es sollte ja deiner meinung nach untereinander sein. Muss ich noch irgendwas einstellen spielt da irgendiowe ContentPresenter ne rolle?

    später würde ich gern verschiede subwindows abgleiten von meinem subwindow erstellen und verwenden, dabei sollen die diveren subwindows, natürlich die Control (titelleiste, buttons) des subwindow haben.



  • ups - stimmt - war n denkfehler von mir - es wird nicht angehangen sondern schlichtweg ersetzt - schade da muss man nu ein kleinen umweg gehen
    man muss ein clientbereich definieren unterhalb des borders und diesen fuellen lassen mittels property
    hier mal das selbe umgebaute beispiel

    UserControl welches ein border hat und ein "anzeigebereich"

    //UserControl xaml
    <UserControl x:Class="MDI_Test.Controls.SubWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="100" Width="100">
        <Grid>
            <Border BorderThickness="2" BorderBrush="Black" />
            <Grid Margin="3" x:Name="ChildArea" />
        </Grid>
    </UserControl>
    
    //UserControl xaml.cs
    namespace MDI_Test.Controls
    {
        public partial class SubWindow : UserControl
        {
            public SubWindow()
            {
                InitializeComponent();
            }
    
            public static readonly DependencyProperty ChildContentProperty = DependencyProperty.Register("ChildContent", typeof(object), typeof(SubWindow), new UIPropertyMetadata(SubWindow.ChildContentValueChanged));
            public object ChildContent
            {
                get { return (string)GetValue(ChildContentProperty); }
                set { SetValue(ChildContentProperty, value); }
            }
            private static void ChildContentValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                SubWindow subWindow = (SubWindow)d;
                subWindow.ChildArea.Children.Add((UIElement)e.NewValue);
            }
        }
    }
    

    Window was dieses ein bindet und den anzeigebereich fuellt

    <Window x:Class="MDI_Test.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:MDI_Test.Controls"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <controls:SubWindow>
                <controls:SubWindow.ChildContent>
                    <StackPanel>
                        <Button Content="SubButton" />
                    </StackPanel>
                </controls:SubWindow.ChildContent>
            </controls:SubWindow>
        </Grid>
    </Window>
    


  • hervorragend mir Evil;) Bist ein gute Mann... und wie würdest du das ganze machen, wenn du jetzt ein Basis UserControl erstellt mit der Titelleiste und buttons, und dann später neue Usercontrol hinzufügest, welche von dem anderen Ableiten und bei denen dann der Clientbereich gefült wird?

    Hoffe du kannst mir folgen;)



  • danke {o;

    ganz einfach - eine neue klasse erstellen (KEIN UserControl erstellen da sonst eine xaml generiert wird, es wird nur die *.cs gebraucht)
    und diese einfach von SubWindow ableiten

    anhand meines vorherigen beispiels:

    namespace MDI_Test.Controls
    {
        class SubWindow2 : SubWindow
        {
        }
    }
    
    <StackPanel>
        <controls:SubWindow>
            <controls:SubWindow.ChildContent>
                <StackPanel>
                    <Button Content="SubButton1" />
                </StackPanel>
            </controls:SubWindow.ChildContent>
        </controls:SubWindow>
        <controls:SubWindow2>
            <controls:SubWindow2.ChildContent>
                <StackPanel>
                    <Button Content="SubButton2" />
                </StackPanel>
            </controls:SubWindow2.ChildContent>
        </controls:SubWindow2>
    </StackPanel>
    

    also man erstellt das UserControl als "MDIDialogTemplate" und alle "MDI fenster" leitet man einfach davon ab und erstellt den content



  • das mit der klasse hab ich schon hinbekommen, bin gut gell;) hat auch funktioniert, allerding hab ich da nen button im code angelegt

    namespace RenaProtoype.MyControls
    {
        class Class1 : SubWindow
        {
            public Class1()  {
                this.ChildContent = new Button();
    
            }
    
        }
    }
    

    und in deinem beispiel machst du den content ja mit xaml. Aber eine "normale" Klasse hat keinen XAML Teil. Verstehste?
    Cool wäre es, wenn jede klasse einen eigen XAML teil hätte wie andere Controls auch, so das ich den content nicht jeweils im hauptfenster definieren müsste.



  • Wegen verschiebbar und so...
    vielleicht hilft dir zusätzlich einer der folgenden Links aus meiner Linksammlung noch weiter, ich beschäftige mich aber selbst gerade nicht damit, so das ich sie nicht bewerten kann:

    WPF Docking Library
    DotNetBar for WPF (kommerzielle Bibliothek)
    SandDock for WPF (kommerzielle Bibliothek)

    cu André



  • also davon erben mit eigener xaml - da wuesste ich grad nix - wuerden wenn dann die anderen elemente der base xaml ueberdeckt werden - glaub nicht das das geht

    also entweder stets den ganzen boarder zeug kopieren oder den content per code erstellen oder den content in der main window erstellen - diese drei optionen wuesste ich nu



  • achso eine idee haette ich noch
    was haellst du davon den content in einer page zu definieren
    und dann in der mainwindow des in dem usercontrol packen ?

    <controls:SubWindow>
        <controls:SubWindow2.ChildContent>
            <controls:SubWindow2Page />
        </controls:SubWindow2.ChildContent>
    </controls:SubWindow>
    

    // hmm - scheint nicht zu funktionieren /=



  • hmm ist ne blöde sache.. hab mir grad überlegt, ob es nich gehen würde, wenn ich einfach normale WPF Windows als Child in einem Haupt WPF Window benutze.. oder gehts das nich gut? ich müsste es halt so machen, das die Child Windows nur in einem Bereich "Childarea" des Haupfenster sichtbar sind und ich sie nicht aus dem hauptfenster ziehen kann.

    Oder ist das ne schlechte Idee? ich denke schon



  • habs hinbekommen

    aaaaaaaaaaalso
    du hast dein UserControl welches nur den rahmen und das "ChildContent" property bereit stellt
    nun definierst du ein subwindow indem du
    eine Page erstellst mit deinen inhalt

    in in dem fenster wo es angezeigt werden soll dann nur noch:

    <controls:SubWindow2>
        <controls:SubWindow2.ChildContent>
            <Frame Source="Controls/SubWindow2Content.xaml" /> <!-- in dieser page hast du dein content des sub windows definiert -->
        </controls:SubWindow2.ChildContent>
    </controls:SubWindow2>
    

    deine idee geht nicht - ein "Window" muss in nem root sein, dh du kannst es nicht einbinden - darum ja der umweg {o;



  • ja danke werde deine Idee, mal testen . du hast es halt drauf;) Zu der Window geschichte.. ja ich binde die Fenster (Subwindo) nich in die Parentfenster ein, sonder ich übergeb den Subwindow den clientBereich. Wenn ich nun dne Subwindow verschiebe vergrößere etc. pürfe ich ob die größe nicht über das hauptfenster hinaus geht. Naja, alles andere als elegant;)

    deine idee ist super, allerding wird es ein krampf die Verschiebe/Vergrößere/Minimiere logik zu programmieren,



  • aber das brauchst du ja nur einmal in den SubWindowBorder element #gg (Die Page musste sich automatisch anpassen)
    der nachteil ist da nu nur, das du den content nicht live beim entwickeln in der mainwindow siehst, da wird nur "Frame" angezeigt

    waere dieses topic nix fuer die FAQ wenn ichs n bissl zusammenfasse? also "MDI in WPF" #gg



  • ok ich checks mal ab. Spiel grad bischen mit WPF Window rum, wie bekomm ich da Origin Postion des Fenster?

    bzw. wie finde ich die Pixel postion eine canvas in einem fenster aufm aufm bildschirm heraus?


Anmelden zum Antworten