WPF: вызов метода из другой "ветви" дерева - PullRequest
1 голос
/ 12 мая 2010

Эй, я делаю приложение WPF.

Дерево выглядит так:

SurfaceWindow --- Начальный экран
..........................-------- Страница ---------- Подстраница

Я пытаюсь вызвать метод из «Подстраницы» из «Код позади» экрана Startscreen.xaml.cs).

Метод с подстраницы выглядит так:

публичный void showTheme (тема ThemeViewModel) { ... }

Если знаете, что я могу вызвать его, когда я нахожусь на «Странице» или «SurfaceWindow», потому что он находится в той же самой «ветви» дерева, и я просто делаю что-то вроде этого:

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

Но как мне это сделать, когда я не нахожусь в одной ветви дерева и хочу вызвать метод?

Ответы [ 2 ]

1 голос
/ 13 мая 2010

Я повторю комментарий Дж. Рота о том, что ваша терминология сбивает с толку. Однако я также сделаю удар в этом.

Мне кажется, что вы хотите, чтобы какое-то событие на вашем "StartScreen" вызывало метод на вашей "Подстранице". Возникает вопрос: а что, если есть несколько «Подстраниц»? Предположим, вы хотите позвонить им всем.

Техника, которую я бы порекомендовал, заключается в том, чтобы ваша «Подстраница» связывалась с некоторыми глобальными данными, чтобы узнать, какой вид они должны отображать в любой момент времени. Обычно я предпочитаю привязку данных для этого, поэтому сначала покажу.

Самый простой способ сделать это с помощью привязки данных - это иметь свойство в вашем объекте Application (или некотором другом статическом объекте), которое является текущей темой. Вместо вызова subpage.ShowTheme () любой код, который изменяет тему, просто обновит свойство темы:

MyApp.Current.Theme = theme;

Теперь подстраница может использовать привязку данных, чтобы привязать тему к одному из своих свойств в стиле по умолчанию:

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

В определении свойства темы подстраницы используйте PropertyChangedCallback для обновления представления:

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

В общем, это лучший способ для таких вещей, как изменения вида, но иногда вы хотите распространять события. Обычно это делается с помощью таких команд:

command.Execute(null, Keyboard.FocusedElement);

Но это работает, только если фокус установлен где-то внутри цели. В вашем случае вы хотите отправить команду в конкретное окно. Если у вас есть только один элемент управления Subpage, он может подписаться на событие в объекте приложения:

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

и события смены темы будут:

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

Опять же, если это вообще возможно, я бы использовал технику привязки данных.

1 голос
/ 12 мая 2010

Можете ли вы предоставить более подробную информацию? Ваша терминология может означать разные вещи. Если вы хотите, чтобы вы вызывали метод с именем showTheme для элемента управления, называемого katalogBlatt, вне родительского элемента управления, то вам нужно либо предоставить метод родительского элемента для вызова метода дочерних элементов управления:

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

и назовите его так:

page.ShowTheme(theme)

или вам нужно предоставить элемент управления как общедоступное свойство для родителя:

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

и назовите его так:

page.Catalog.ShowTheme(theme);
...