Применить Ninject для работы с "дочерними моделями представления" в моем приложении C # WPF - PullRequest
0 голосов
/ 13 декабря 2018

У меня возникли проблемы с выполнением Ninject - инъекцией зависимостей - в моем приложении WPF.

Мне удалось правильно выполнить инъекцию зависимостей для моих MainView.xaml и MainViewModel.cs, я сделал этопо настройкам текстового контекста в моем App.xaml.cs.После этого я установил для моего файла данных MainWindow видовую модель, полученную ядром из ninject.

Вот мой App.xaml.cs, который я установил как Startup вместо StartupUri в app.xaml

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var kernel = new StandardKernel(new CompositionModule());

        MainWindow mainWindow = new MainWindow();
        mainWindow.DataContext = kernel.Get<MainViewModel>();
        mainWindow.Show();
    }

Пока что он отлично работает для MainViewModel, но моя проблема в том, что у моей MainViewModel есть несколько дочерних моделей представления.

Вот пример моей дочерней модели представления - настройка, на которую мой MainView.xaml выглядит так - Из-под вы можете видетьчто мой MainView.xaml разделил главное окно на две части.Одна часть главного окна показывает view1 и viewmodel1, а другая часть показывает view2 и viewmodel2.Оба находятся в одном окне, я сделал это только для того, чтобы было легче показать, что делают эти части.Моя проблема в том, что теперь я связываю Content = Viewmodel1, но когда я пытаюсь поместить значение параметра в конструктор, мое приложение не выполняет код конструктора.Это просто пропускает это.Мои дочерние viewmodels относятся к частичному классу, который состоит из viewmodel1.cs и viewmodel.commands.cs.Часть viewmodel.commands содержит только команды для графического интерфейса.ContentTemplate представляет собой шаблон данных в моем ресурсе xaml - файлах ресурсов с ресурсами, загруженными в app.xaml.

<telerik:RadSplitContainer Orientation="Vertical" telerik:DockingPanel.InitialSize="750,200">
            <telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="200,300" >
                <telerik:RadPane Header="{Binding ViewModel1.Title, Mode=TwoWay}" 
                             CanUserClose="False" CanUserPin="False"
                             CanDockInDocumentHost="True">
                    <ContentControl ContentTemplate="{StaticResource View1Template}"  
                                Content="{Binding Viewmodel1}" />
                </telerik:RadPane>
            </telerik:RadPaneGroup>
            <telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="100,120">
                <telerik:RadPane Header="ViewModel2.Tile" 
                             CanUserClose="False" CanUserPin="False"
                             CanDockInDocumentHost="True">
                    <ContentControl ContentTemplate="{StaticResource View2Template}"  
                                Content="{Binding Viewmodel2}" />
                </telerik:RadPane>
            </telerik:RadPaneGroup>
         </telerik:RadSplitContainer>

Эти две модели представления привязываются к содержимому в MainView.xaml.

public ViewModel1 ViewModel1 { get; set; } = new ViewModel1();
public ViewModel2 ViewModel2 { get; set; } = new ViewModel2();

Как можноСделать инъекцию зависимостей также для моих дочерних моделей просмотра?Кажется, причина того, что это не работает, в том, что конструктор никогда не запускается, когда я указываю интерфейс в качестве параметра конструктора.

Спасибо за любую помощь, которую я могу получить.Он отлично работает для MainViewModel, но не для моих файлов ресурсов и других моделей представления.

1 Ответ

0 голосов
/ 13 декабря 2018

Я отправил этот код на ваш предыдущий вопрос.Когда вы устанавливаете

public ViewModel1 ViewModel1 { get; set; } = new ViewModel1();

Тогда это будет игнорировать ninject.Вы только что создали новый класс.

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

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var nj = new StandardKernel();
        nj.Bind<IVMOne>().To<VMOne>().InTransientScope();  //  <<<<<<<<<<<<<<<

        MainWindow mw = new MainWindow();
        mw.DataContext = nj.Get<MainWindowViewModel>();
        mw.Show();
    }

Видите, где я связываю IVMOne?Это эквивалентно вашим Viewmodel1 и 2. У вас этого нет в вашем коде.

Когда я получаю MainWindowViewModel с IVMOne в качестве параметра ctor.

class MainWindowViewModel
{
    public IVMOne VMOne { get; set; }
    public MainWindowViewModel(IVMOne vmOne)
    {
        VMOne = vmOne;
    }
}

Потому что я сказал эточто дать мне, он передает экземпляр VMOne.

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

    Title="MainWindow" Height="450" Width="800">
<Grid>
    <TextBlock Text="{Binding VMOne.Hello}"/>
</Grid>

Если я ставлю точку останова на mainwindowviewmodelctor У меня там есть экземпляр vmone.

Не могли бы вы попробовать связать одну из ваших моделей представления перед получением mainwindowviewmodel?

Когда вы получаете mainwindowviewmodel, он будет использовать ctor с большинством параметров.Поставьте точку останова в этом.У вас есть экземпляр вашей модели представления там?

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

Так кто-то может легко и быстро воспроизвести вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...