views:

41

answers:

2

Hey, I'm doing a WPF Application.

The tree looks like this:

SurfaceWindow --- Startscreen
..........................-------- Page---------- Subpage

I'm trying to call a method from the "Subpage" from the "Code Behind" of the Startscreen(Startscreen.xaml.cs).

The method from the Subpage looks like this:

public void showTheme(ThemeViewModel theme) { ... }

If know that I can call it when I'm on the "Page" or the "SurfaceWindow", because it's in the same "branch" of the tree, and I just do something like this:

        ThemeViewModel theme = (ThemeViewModel)mvm.CurrentItem.ThemeViewModel;
        katalog.katalogblatt.showTheme(theme);

But how do I do it when I'm not on the same branch of the tree and want to call the method?

+1  A: 

Can you provide more detail? your Terminology can mean various things. Providing you mean you want to call a method called 'showTheme' on a control called 'katalogBlatt' outside of the parent control then you either need to expose a method on the parent to call the child controls method:

public void ShowTheme(ThemeViewModel theme)
{
   this.katalogBlatt.ShowTheme(theme)
}

and call it as:

page.ShowTheme(theme)

or you need to expose the control as public property on the parent:

public <controlType> Catalog
{
   get
   {
      return katalogBlatt;
   }
}

and call it as:

page.Catalog.ShowTheme(theme);
J Rothe
Thank you. This is exactly what I wanted to do.PS: Sorry for being imprecise with my question but my English is not so good.
sofri
+1  A: 

I'll second J Rothe's comment that your terminology is confusing. However I'll also take a stab at this.

It seems to me that you want some event on your "StartScreen" to invoke a method on your "Subpage". This begs the question of what if there are multiple "Subpages". Let's assume you want to call them all.

The technique I would recommend is that your "Subpage" bind to some global data to learn which view it should be showing at any given time. I would generally prefer data binding for this, so I will show that first.

The simplest way to do this using data binding is to have a property in your Application object (or some other static object) that is the current theme. Rather than calling subpage.ShowTheme(), any code that changes the theme would simply update the theme property:

MyApp.Current.Theme = theme;

Now Subpage can use data binding to get the theme bound to one of its own properties in its default style:

<Style TargetType="my:Subpage">
  <Setter Property="Theme" Value="{Binding Theme, Source={x:Static my:MyApp.Current}}" />
</Style>

In the definition for Subpage's Theme property, use a PropertyChangedCallback to update the view:

public static readonly DependencyProperty ThemeProperty = DependencyProperty.Register("Theme", typeof(MyTheme), typeof(Subpage), new PropertyMetadata
{
  PropertyChangedCallback = (obj, e) =>
  {
    ((Subpage)obj).SetTheme((Theme)e.NewValue);
  }
});

In general this is the best way for things like view changes, but at times you want to propagate events. Normally this would be done using commands like this:

command.Execute(null, Keyboard.FocusedElement);

But this only works if the focus is set somewhere within the target. In your case you want to send the command to a specific window. If you only ever have one Subpage control, it can subscribe to an event in the application object:

public Subpage()
{
  MyApp.Current.SwitchTheme += (obj, e) => setTheme(e.NewTheme);
}

and theme change events would be:

MyApp.Current.SwitchTheme(null, new ThemeChangeEventArgs { NewTheme = theme });

Again, if at all possible I would use the data binding technique.

Ray Burns