Laden...

Probleme mit der AddHandler-Methode

Erstellt von PaulSch vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.246 Views
P
PaulSch Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren
Probleme mit der AddHandler-Methode

Hallo ,

ich möchte gern in einem untergeordneten Control einen Event eines übergeordneten Controls abbonieren.

Im folgenden Beispiel soll also die Methode 'Methode_A' ausgeführt werden, wenn das Ereignis 'PreviewMouseDownEvent' im MainWindow eintritt.

ein simples Beispiel dazu (Window mit Grid, Stackpanel und Button ineinanderliegend und farblich voneinander abgesetzt):

XAML:


<Window x:Class="Demo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Background="Gray" Margin="50">
        <StackPanel Name="stackpanel" Background="Blue" Margin="50">
            <Button Margin="20" Content="Ok"></Button>
        </StackPanel>
    </Grid>
</Window>

und der Code dazu:


namespace Demo
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            stackpanel.AddHandler(MainWindow.PreviewMouseDownEvent, new RoutedEventHandler(Methode_A), true); 
        }

        void Methode_A(Object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hier Methode A"); 
        }
    }
}

Wenn ich dieses nun starte und in den weissen Bereich des Window klicke, dann wird meine Methode_A aber nun NICHT ausgeführt, , obwohl doch das Ereignis 'PreviewMouseDownEvent' auf jeden Fall eingetreten ist.

Wo ist mein Denkfehler, bzw. wie erreiche ich mein Wunschziel ?

viele Grüße
Paul

5.299 Beiträge seit 2008
vor 11 Jahren

mir scheint, du behandelst nur das PreviewMouseDown des Stackpanels.
Aber im weißen Bereich ist das STackpanel doch garnet.

Der frühe Apfel fängt den Wurm.

P
PaulSch Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren

Guten Morgen Erfinder,

mir scheint, du behandelst nur das PreviewMouseDown des Stackpanels.

woraus schließt du das ? In der AddHandler-Methode gebe ich doch mit "MainWindow.PreviewMouseDownEvent" explizit den Event des MainWindow an ?

Ich war bisher der Meinung, mit AddHandler wird einfach nur in irgendeiner internen Liste im System eine (nämlich meine angegebene) Methode zugefügt, damit diese beim Eintreffen eines Events abgearbeitet wird ... anscheinend ist dies nicht so - deswegen also meine Frage an die Wissenden hier; wie kann ich einen Event eines übergeordneten Controls abonieren ?

viele Grüße
Paul

6.862 Beiträge seit 2003
vor 11 Jahren

Hallo,

ErfinderDesRades hat Recht.

PreviewMouseDownEvent ist eigentlich ein Attached Event der Mouse Klasse. Das PreviewMouseDown Event im Window und im StackPanel sind exakt das identische Event, sie sind nämlich nur Aliase auf das Attached Event der Mouse Klasse und werden auch nicht durch Window bzw. StackPanel deklariert, sondern schon allgemein von UIElement.

Wenn du also

 stackpanel.AddHandler(MainWindow.PreviewMouseDownEvent,...

schreibst, abonierst du das Event beim StackPanel.

Nichtsdestotrotz ist das hier völlig irrelevant da das PreviewMouseDown Event natürlich nen Tunneling Event ist. Daher abonier das einfach wo du willst und du musst einfach nur aus den Argumenten beachten wer der OriginalSender ist.

Baka wa shinanakya naoranai.

Mein XING Profil.

P
PaulSch Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren

Hallo talla,

ok, so langsam dämmert es, dass beim Klick auf den Windowbereich der Mouseevent ja gar nicht beim Stackpanel aufgetreten ist und deshalb ein vom Stackpanel aboniertes Ereignis auch nicht auftreten kann ...

wieder etwas gelernt, was ich eigentlich gar nicht gefragt hatte und in meiner Unkenntnis ein unpassendes Beispiel konstruiert hatte ... 😉

das hilft mir aber leider nicht bei meinem ursprünglichen Problem:

... ich möchte gern in einem untergeordneten Control einen Event eines übergeordneten Controls abonieren. ... (siehe oben)

.. konkret geht es darum, das ich ein WPF-Fenster habe, in dieses werden - je nach Anforderung diverse Usercontrols geladen - und in diesen Usercontrols muss ich wissen, wenn sich im WPF-Fenster ein Zustand geändert hat. Also habe ich im WPF-Fenster einen Event erstellt und wollte in den Usercontrols mich einfach dranhängen - das klappt aber nicht.

viele Grüße
Paul

5.299 Beiträge seit 2008
vor 11 Jahren

so geht das glaub nicht.
Ein untergeordnetes Element abonniert nicht die Events seines Parents, sondern wird direkt von ihm manipuliert - gugge VeryBasics

Ich würde eher versuchen, was übers Viewmodel zu reißen.

Ansonsten müsstest du glaub wirklich mal konkret werden - so kann man ja ewig herumspekulieren.

Der frühe Apfel fängt den Wurm.

6.862 Beiträge seit 2003
vor 11 Jahren

Das Control sollte sein Parent egal sein. Trotzdem hast du die Lösung schon erhalten. Du kannst dir einfach ein RoutedEvent mit Tunneling erstellen. Dann bekommst du auch in dem Child das Event wenn das Window es auslöst.

Aber auch der Hinweis auf das ViewModel von ErfinderDesRades ist natürlich korrekt. Gerade wenn du sagst Zustand willst du ja auf gemeinsame Daten zugreifen.

Baka wa shinanakya naoranai.

Mein XING Profil.

P
PaulSch Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren

Hallo talla,

Du kannst dir einfach ein RoutedEvent mit Tunneling erstellen. Dann bekommst du auch in dem Child das Event wenn das Window es auslöst.

... das geht eben gerade nicht, das hatte ich nämlich probiert. Der Grund ist mir - jetzt hinterher - schon klar: Da ja das Ereignis nur bis dahin tunnelt, wo es quasi auftritt, geht es nicht tiefer als die Ebene "Window". Meine Trugschluß war, das ein "Tunneling-Event" immer die ganze Control-Struktur durchläuft, das tut er aber nicht - sondern er läuft nur bis zum Eventauslösenden Control und dann wieder hinauf (sofern auch noch was zum Bubblen definiert wurde).

@ErfinderDesRades

so geht das glaub nicht.
Ein untergeordnetes Element abonniert nicht die Events seines Parents

... genau das wollte ich aber tun. Mein Problem war, ich habe zur Designzeit keine Referenz auf mein "MainWindow" um per " ...+= ..." den Event zu abonieren. Durch einen kleinen Trick klappt das nun aber. Ich erstelle das Abo nicht wie üblicherweise beim Init meines Controls, sondern einfach in einer eigenen Methode . Diese Methode wird durch das 'MainWindow' nach der Initialisierung aufgerufen und schon klappt es.

vielen Dank für eure Bemühungen und Denkanstöße

viele Grüße
Paul