Entwickler-Ecke

WPF / Silverlight - Von einer Page das Menu des Window auf isEnabled true setzen


new.Matrix - Sa 26.04.08 09:29
Titel: Von einer Page das Menu des Window auf isEnabled true setzen
Hallo Zusammen,

Wie kann ich von einer Page auf das Menun der Window die die Page hostet zugreiffen?

Also ich hab ein MainWindow.xaml habe dort ein Menu mit Öffnen, Speichern etc... Nun möchte ich, dass Speichern nur in einem bestimmenten Page anklickbar ist. Beim Laden der Window wird nun Save.IsEnable = false; gesetzt, soweit klappts auch. Nur weiss ich jetzt nicht wie ich von der Page aus auf Save zugreiffen kann. Wie geht das?


Kha - Sa 26.04.08 10:52

Der saubere Weg:


new.Matrix - Sa 26.04.08 11:57

Erstmals Danke für deine Hilfe!

Sry für die Newbe Frage aber, wie gebe ich genau die IsSaveable Property dem CanExecute-Handler des CommandBindings zurück?

ich habs mal soweit hinbekommen:

Das ist der Code des Hauptfensters, hoffe ist soweit richtig

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
        public Window1()
        {
            InitializeComponent();
            DoCommandBinding();
        }

    void DoCommandBinding() {
            CommandBinding OpenCmdBinding = new CommandBinding(ApplicationCommands.Open, OpenCmdExecuted, OpenCmdCanExecute);
            CommandBinding SaveCmdBinding = new CommandBinding(ApplicationCommands.Save, SaveCmdExecuted, SaveCmdCanExecute);
            this.CommandBindings.Add(OpenCmdBinding);
            this.CommandBindings.Add(SaveCmdBinding);
        }

        void OpenCmdExecuted(object target, ExecutedRoutedEventArgs e)
        {
            String command, targetobj;
            command = ((RoutedCommand)e.Command).Name;
            targetobj = ((FrameworkElement)target).Name;
           // MessageBox.Show("The " + command + " command has been invoked on target object " + targetobj);
        }
        void OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        void SaveCmdExecuted(object target, ExecutedRoutedEventArgs e)
        {
            String command, targetobj;
            command = ((RoutedCommand)e.Command).Name;
            targetobj = ((FrameworkElement)target).Name;
            // MessageBox.Show("The " + command + " command has been invoked on target object " + targetobj);
        }
        void SaveCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = false;
        }


Soweit so gut, Öffnen klappt (ausser das das mit Str-O nicht klappt, weshalb weis ich auch nicht) und auf Speichern kann ich nicht klicken wie gewollt.

Nun habe ich in der Page Klasse das IsSaveable so definiert:


C#-Quelltext
1:
2:
3:
4:
5:
6:
        private Boolean _Saveable;
        public Boolean Saveable
        {
            get { return _Saveable; }
            set { _Saveable = value; }
        }


Hoffe das ist mal richtig und nun sage ich sobald die Page geladen ist Saveable = true... Wie gebe ich es jetzt dem CanExecute Handler zurück?


Kha - Sa 26.04.08 16:10


C#-Quelltext
1:
e.CanExecute = deinePage.Saveable;                    

;) ?


new.Matrix - Di 29.04.08 10:26

Hmmm....

Ich habe Ja Saveable nicht zur Verfügung in MainWindow da das propery Saveable in der Page Klasse definiert ist und diese zu diesem Zeitpunkt nicht instanziert...
der Sinn verstehe ioch, aber wie setze ich es um? Wenn ich das Savable Property in der MainWindow Klasse definiere dann kann wiederum von der Pageklasse nicht darauf zugreiffen :-S


Kha - Di 29.04.08 13:17

Vielleicht sollte ich mich doch irgendwann einmal mit Pages auseinandersetzen *g* ...
Nächste Idee: Wenn nur eine bestimmte Page speicherbar ist, dann sollte doch auch etwas wie

C#-Quelltext
1:
e.CanExecute = frame.Source.OriginalString == "blubb.xaml";                    

funktionieren.


new.Matrix - Di 29.04.08 14:11

Hmm, es gibt mir zwar keine Fehlrmeldung aus, dennoch tut sich nichts...

Habe irgendwo folgenden Code aufgeschappt:


C#-Quelltext
1:
2:
3:
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save,
            new ExecutedRoutedEventHandler(delegate(object sender, ExecutedRoutedEventArgs e) {}),
            new CanExecuteRoutedEventHandler(delegate(object sender, CanExecuteRoutedEventArgs e){})));


Dabei stand, dass dann automatisch das Programm erkennt ob sich ein command save befindet... aber wie definiere ich dann das command save?


new.Matrix - Di 29.04.08 14:23

Korrgiere! Nun funztz! danke schöön! Habs jetzt mit deiner Lösung hinbekommen :-D

weisst du vielleicht gleich auch noch wie man ShortKeys hinzufügt? Also nicht die Darstellung sondern die Funktion...


Christian S. - Di 29.04.08 14:33

user profile iconKhabarakh hat folgendes geschrieben:
Nächste Idee: Wenn nur eine bestimmte Page speicherbar ist, dann sollte doch auch etwas wie

C#-Quelltext
1:
e.CanExecute = frame.Source.OriginalString == "blubb.xaml";                    

funktionieren.
Sauberer fände ich es, ein Interface ISaveable einzuführen und bei der Page, die diese Funktion bietet, das Interface zu implementieren. Dann kann man abfragen:


C#-Quelltext
1:
e.CanExecute = theFrame.Content is ISaveable                    


Und ist unabhängig von irgendwelchen Dateinamen.


new.Matrix - Di 29.04.08 16:51

...habs versucht sauber zu lösen aber jetzt klappts nicht mehr... also so gemacht:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
    interface IIsSavable
    {
        Boolean IsSaveable
        {
            get;
            set;
        }
    }

    class IsSavable
    {
        private Boolean _IsSaveable;
        public Boolean IsSaveable
        {
            get { return _IsSaveable; }
            set { _IsSaveable = value; }
        }
    }



und dann in der Page:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
        public PositionResults()
        {
            InitializeComponent();
            IsSavable _Savable = new IsSavable();
            _Savable.IsSaveable = true;
            //IIsSavable = true;
        }


wo ist mein überlegungsfehler?


Christian S. - Di 29.04.08 16:57

Öhm, das macht ja mal so gar keinen Sinn. Du deklarierst ein Interface und benutzt es dann nicht. Und dann erstellst Du eine Klasse, die nichts mit Deiner Page zu tun hat. :nut:

Was ich meinte, ist das hier:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
public class PositionResults : Page, ISaveable
{
   /* ... das Zeug, was so in einer Page drin steht ...*/
}


public interface ISaveable
{
}


Ins Interface sollten dann noch die Methoden rein, die Deine Page implentieren muss, um "speicherbar" zu sein. Wenn das keine Methoden sind, kannst Du das Interface sogar leer lassen.


new.Matrix - Di 29.04.08 17:52

:oops:
Danke vielmals, jetzt funzts auch sauber... hatte bis noch nie mit interface zu tun...

Wie kann ich es realisieren, dass wenn ich auf der Tastatur Str+O drücke dann der Opendialog geöffnet wird?


Kha - Di 29.04.08 21:26

Den saubersten Weg solltest du dir langsam denken können: Commands ;) . Stichwort: KeyBinding.

user profile iconChristian S. hat folgendes geschrieben:
Sauberer fände ich es, ein Interface ISaveable einzuführen und bei der Page, die diese Funktion bietet, das Interface zu implementieren.
Bei einer einzigen Page hatte meine Faulheit mich besiegt :mrgreen: . Dann hätte ich aber erst gar nicht mit den Commands anfangen dürfen :gruebel: . Achja: Ein geeigneter Interface-Member wäre wohl Save(string path) *g* .