Отделите экраны без волшебных строк

Мой проект WPF будет организован как это:

Screens
   Group1
      Screen1
         View.xaml
         ViewModel.cs
   Group2
      Screen2
         View.xaml
         ViewModel.cs

Показать Screen1 от Screen2 Я буду использовать что-то вроде этого: ScreenManager.Show("Group1.Screen1") Это смотрит (использование отражения) в Screens.Group1.Screen1 пространство имен для Представления и ViewModel и инстанцирует их.

Как я могу устранить волшебную строку без связи Screen1 и Screen2 (Я не хочу классы в Screen2 использовать Screen1 пространство имен). Также я хотел бы некоторое экранное исследование (autocompletion/intellisense)

Или возможно некоторый путь (автоматизируют тест) проверить что все вызовы к ScreenManager.Show допустимы.

Обновление: Я придумал это:

public class ScreenNames
{
    public Group1Screens Group1;

    public class Group1Screens
    {
        public ScreenName Screen1;
    }
}

public sealed class ScreenName
{
    private ScreenName() { }
}

public class ScreenManager : IScreenManager
{
    public void Show(Expression<Func<ScreenNames, ScreenName>> x) {}
}

Использование:

screenManager.Show(x=>x.Group1.Screen1);

Не идеальный, но я предполагаю нарушение, DRY еще лучше, чем волшебные строки. И я могу автоматически протестировать (с отражением), что все вызовы допустимы.

6
задан Catalin DICU 10 February 2010 в 21:27
поделиться

2 ответа

Наконец, я использовал генерацию кода T4 для создания моего класса ScreenNames . Я сделал это, адаптировав этот код: Автоматически создавать строго типизированный класс навигации для всех пользовательских элементов управления в веб-приложении ASP.NET

0
ответ дан 17 December 2019 в 18:15
поделиться

Вам не нужен весь этот ScreenManager в WPF, потому что механизм DataTemplate может позаботиться об этом за вас с помощью чистой разметки.

Вы можете просто привязать данные к определенной области вашего приложения с помощью ContentPresenter и набора DataTemplates. Свяжите область со свойством «корневой» ViewModel и позвольте «корневой» ViewModel реализовать INotifyPropertyChanged, чтобы WPF знал, измените ли вы ViewModel в этой области.

public class RootViewModel : INotifyPropertyChanged
{
    public object Screen1ViewModel { get; }

    public object Screen2ViewModel { get; }
}

Свяжите один элемент управления ContentPresenter со свойством Screen1ViewModel, используя

<ContentControl Content="{Binding Path=Screen1ViewModel}" />

и аналогично для следующего. Когда вам нужно изменить содержимое Screen1, вы просто повторно назначаете Screen1ViewModel из кода, и из-за возникшего события PropertyChanged WPF подберет его и привяжет новую ViewModel к новому View.

Шаблоны данных могут быть такими простыми:

<Window.Resources>
    <DataTemplate DataType="{x:Type foo:MyViewModel}">
        <self:MyControl />
    </DataTemplate>
    <DataTemplate DataType="{x:Type foo:MyOtherViewModel}">
        <self:MyOtherControl />
    </DataTemplate>
</Window.Resources>

Если вы не знакомы с ним, эта статья о MVVM в WPF является отличным введением.

3
ответ дан 17 December 2019 в 18:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: