Нужна помощь в приложении wpf с помощью mef - PullRequest
0 голосов
/ 23 февраля 2012

Я подаю заявку в wpf по шаблону MVVM. Мне нужно добавить в него MEF.

Вот базовая архитектура моей программы.

У меня есть основной проект MefApplication. Это только один вид MainWindow.xaml. Он содержит один список и пользовательский элемент управления. Когда приложение запускается, оно загружает модули и перечисляет их в списке. Нажатие на модуль приводит к отображению модуля в пользовательском контроле.

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

Теперь я загрузил модули и перечислил их вниз. При нажатии на модуль отображается первый экран модуля. Но когда я нажимаю кнопку «Далее» в представлении модуля, ничего не происходит. Я не знаю, как перейти к следующему виду. Ниже мой код. Может кто-нибудь скажет мне, где я иду не так.

MainWindow.xaml

<Window x:Class="MefApplication.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>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="40*"/>
        <ColumnDefinition Width="80*"/>
    </Grid.ColumnDefinitions>
    <ListBox x:Name="listBox" Grid.Column="0" 
    ItemsSource="{Binding Modules}" SelectedItem="{Binding SelectedModule, Mode=TwoWay}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding ModuleName}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Content="{Binding UserInterface}"/>
</Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowViewModel();
    }
}

MainWindowViewModel.cs

class MainWindowViewModel : INotifyPropertyChanged
{
    #region NotifyOfPropertyChanged
    #endregion

    private string _path = "Path to Modules Dll Folder"; 
    public MainWindowViewModel()
    {
        Modules = GetModules(_path);
        SelectedModule = Modules[0];
    }

    public List<IMainModule> GetModules(string path)
    {
        var directoryCatalog = new DirectoryCatalog(path);
        var container = new CompositionContainer(directoryCatalog);
        var modules = container.GetExportedValues<IMainModule>().ToList();
        return modules;
    }

    private IMainModule selectedModule;

    public List<IMainModule> Modules { get; set; }

    public IMainModule SelectedModule
    {
        get { return selectedModule; }
        set
        {
            if (value != selectedModule)
            {
                selectedModule = value;
                NotifyOfPropertyChange("SelectedModule");
                NotifyOfPropertyChange("UserInterface");
            }
        }
    }

    public UserControl UserInterface
    {
        get
        {
            if (SelectedModule == null)
                return null;
            return SelectedModule.UserInterface;
        }
    }
} 

Это интерфейс модуля. Содержит имя модуля и его начальный вид.

public interface IMainModule
{
    string Name { get; }
    UserControl UserInterface { get; }
} 

Это один из моих модулей. ServerWindowModule. Это возвращает UserControl одного из моих представлений в модуле (ServerWindow).

[Export(typeof(IMainModule))]
class ServerWindowModule : IMainModule
{
    public string Name
    {
        get { return "Server Module"; }
    }

    public UserControl _userInterface { get; set; }
    public UserControl UserInterface
    {
        get { return _userInterface ?? (_userInterface = new ServerWindowView()); }
    }
} 

Это один из моих взглядов. ServerWindowView.

public partial class ServerWindowView : UserControl
{
    public ServerWindowView()
    {
        InitializeComponent();
        DataContext = new ServerWindowViewModel();
    }
} 

Теперь вот ViewModel для ServerWindowViewModel.

publicclassServerWindowViewModel : INotifyPropertyChanged
{
    #region NotifyOfPropertyChanged
    #endregionpublic ServerWindowViewModel()
    {
        LabelText = "Constructor set this.";
    }

    publicstring LabelText { get; set; }

    privateICommand _nextCommand;
    publicICommand NextCommand
    {
        get { return _nextCommand ?? (_nextCommand = newRelayCommand(NextFunction)); }
    }

    public void NextFunction()
    {
        LabelText = "Button set this.";
        NotifyOfPropertyChange("LabelText");
        // TODO: Navigate to ServerValidation View
        // Here i want to go to my next view(ServerValidationView). What should I write here.
    }
}          

Теперь на кнопке Следующая функция, что мне делать, чтобы заменить текущий вид на ServerValidationView.

Если есть путаница, пожалуйста, спросите.

Спасибо

Ответы [ 2 ]

0 голосов
/ 24 февраля 2012

Caliburn.Micro может помочь вам в этом или в рамке, которую Роб Айзенберг представил на Mix.Он использует свойство зависимости

public static class View
{
    public static DependencyProperty ModelProperty =
        DependencyProperty.RegisterAttached(
            "Model",
            typeof(object),
            typeof(View),
            new PropertyMetadata(ModelChanged)
            );

    public static void SetModel(DependencyObject d, object value)
    {
        d.SetValue(ModelProperty, value);
    }

    public static object GetModel(DependencyObject d)
    {
        return d.GetValue(ModelProperty);
    }

    public static void ModelChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue == null || args.NewValue == args.OldValue)
            return;

        var vm = args.NewValue as IYourModuleProvidingUI;
        var view = vm.UserInterface;

        ((ContentControl)sender).Content = view;
    }
}

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

<ContentControl Framework:View.Model="{Binding SelectedModule}" Padding="2,0,0,2"/>

SelectedViewModel - это свойство, вызывающее событие INotifyPropertyChanged, когда его значение изменилось.То, что будет отображаться, контролируется значением свойства SelectedModule.

0 голосов
/ 24 февраля 2012

Я сейчас занимаюсь чем-то похожим. Я не уверен, что это будет правильный способ справиться с этим, но мой дизайн заключается в том, что каждый модуль будет иметь свою собственную оболочку.

Например, первый вид окна вашего сервера - это оболочка с представителем контента. Чтобы изменить представление в модуле, я бы изменил содержимое на презентере внутри модуля.

Это дикое предположение, основанное на том, что я увидел из http://www.ra -design.at / silverlight / mediaowl /

...