Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
 ViewModel c несколькими DataContext.  [new]
vb_sub
Member

Откуда:
Сообщений: 495
Всем привет. Есть View, у которой есть ее DataContext (MainViewModel) и есть её часть, у которой должна быть своя ViewModel.
<local:BaseView
    x:Class="BrigPlanning.View.View.mainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:BrigPlanning.View.View"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:VM.vm;assembly=VM"
    x:TypeArguments="vm:MainViewModel"
    mc:Ignorable="d">

    <local:BaseView.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Flipper.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </local:BaseView.Resources>

    <Grid Background="Aqua">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>


        <Grid Grid.Row="0" Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <materialDesign:Flipper MaxWidth="800" Style="{StaticResource MaterialDesignCardFlipper}">
                <materialDesign:Flipper.DataContext>
                    <vm:SettingsVM />
                </materialDesign:Flipper.DataContext>

                <materialDesign:Flipper.FrontContent>

                    <Grid Width="200" Height="256">
                        <Button
                            Margin="0,4,0,0"
                            Command="{x:Static materialDesign:Flipper.FlipCommand}"
                            Style="{StaticResource MaterialDesignFlatButton}">
                            EDIT
                        </Button>
                    </Grid>

                </materialDesign:Flipper.FrontContent>

                <materialDesign:Flipper.BackContent>

                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>

                        <TextBlock
                            Grid.Row="0"
                            Grid.ColumnSpan="2"
                            Text="Настройки параметров списка рейсов"
                            TextWrapping="Wrap" />

                        <DatePicker
                            Grid.Row="1"
                            Grid.Column="0"
                            Margin="3"
                            VerticalAlignment="Center"
                            materialDesign:HintAssist.Hint="Дата начала вылета"
                            FlowDirection="LeftToRight"
                            FontSize="16"
                            SelectedDate="{Binding StartDate}" />

                        <materialDesign:TimePicker
                            Grid.Row="1"
                            Grid.Column="1"
                            Margin="3"
                            VerticalAlignment="Center"
                            materialDesign:HintAssist.Hint="Время"
                            FontSize="16"
                            Is24Hours="True"
                            SelectedTime="{Binding StartTime}"
                            Style="{StaticResource MaterialDesignFloatingHintTimePicker}" />

                        <DatePicker
                            Grid.Row="2"
                            Grid.Column="0"
                            Margin="3"
                            VerticalAlignment="Center"
                            materialDesign:HintAssist.Hint="Окончание вылета"
                            FlowDirection="LeftToRight"
                            FontSize="16"
                            SelectedDate="{Binding FinishtDate}" />

                        <materialDesign:TimePicker
                            Grid.Row="2"
                            Grid.Column="1"
                            Margin="3"
                            VerticalAlignment="Center"
                            materialDesign:HintAssist.Hint="Время"
                            FontSize="16"
                            Is24Hours="True"
                            SelectedTime="{Binding FinishTime}"
                            Style="{StaticResource MaterialDesignFloatingHintTimePicker}" />


                        <Button
                            Grid.Row="5"
                            Margin="8"
                            Command="{x:Static materialDesign:Flipper.FlipCommand}"
                            Style="{StaticResource MaterialDesignFlatButton}">
                            GO BACK
                        </Button>
                        <materialDesign:MaterialDateDisplay/>
                    </Grid>

                </materialDesign:Flipper.BackContent>

            </materialDesign:Flipper>
        </Grid>
    </Grid>

</local:BaseView>



ViewModel'и инициализирую с помощью Ioc-контейнера Ninject.

  private static void BindViewModels()
        {

// public static IKernel Kernel { get; private set; } = new StandardKernel();

            Kernel.Bind<IDataProvider>().ToConstant(new DataProvider());
   
            Kernel.Bind<MainViewModel>().ToConstant(new MainViewModel(Kernel));

            Kernel.Bind<SettingsVM>().ToConstant(new SettingsVM(Kernel));

            Kernel.Bind<ApplicationViewModel>().ToConstant(new ApplicationViewModel());

        }


В конструктор ViewModel приходит IoC-контейнер.


    /// <summary>
    /// Модель настроек
    /// </summary>
    public class SettingsVM: BaseViewModel
    {
        private IKernel mkernel;

        #region ViewProps

        public DateTime StartDate { get; set; }

        public DateTime StartTime { get; set; }

        public DateTime FinishtDate { get; set; }

        public DateTime FinishTime { get; set; }

        #endregion



        #region Constructors
        public SettingsVM(IKernel kernel)
        {
            mkernel = kernel;
        }

        public SettingsVM():this(null)
        {
            StartDate = DateTime.UtcNow;
            StartTime = DateTime.UtcNow;
            FinishtDate = DateTime.UtcNow;
            FinishTime = DateTime.UtcNow;

        }
        #endregion

    }


  
    /// <summary>
    /// Основная VM приложения
    /// </summary>
    public class MainViewModel : BaseViewModel
    {
        private IKernel mkernel;


        #region Constractors
        public MainViewModel(IKernel kernel)
        {
            mkernel = kernel;
        }

        public MainViewModel() : this(null)
        {
        }
        #edregion

    }


При задании ViewModel из Xaml
    <materialDesign:Flipper.DataContext>
                    <vm:SettingsVM />
                </materialDesign:Flipper.DataContext>

используется дефолтный пустой конструктор без аргументов и соответственно внедрение зависимостей не работает (kernel=null) (для задания x:TypeArguments="vm:MainViewModel" - работает). Не хочу включать класс SettingsVM как свойство MainViewModel - хочу сделать их несвязанными. Как можно заставить инициализироваться SettingsVM через контейнер зависимостей? Спасибо
19 фев 19, 16:18    [21814485]     Ответить | Цитировать Сообщить модератору
 Re: ViewModel c несколькими DataContext.  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4710
Так диконтейнер же сам инициализирует все модели. Выставьте наружу у обертки диконтейнера статик-свойства, возвращающие нужные модели/сервисы, и подцепляйте их в разметке через x:Static.
P.S. Инициализировать потребителя инжектированных сущностей ядром диконтейнера идеологически неправильно, это прямая дорога к антипаттерну God, и мало чем отличается от сервис-локатора. По фэншую нужно инициализировать каждого потребителя только теми инжектированными классами, которые он использует.
19 фев 19, 16:53    [21814559]     Ответить | Цитировать Сообщить модератору
 Re: ViewModel c несколькими DataContext.  [new]
vb_sub
Member

Откуда:
Сообщений: 495
Сон Веры Павловны,
спасибо Ваш совет мне помог

    public static class Ioc
    {
        /// <summary>
        /// The kernel for our IoC container
        /// </summary>
        public static IKernel Kernel { get; private set; } = new StandardKernel();

        public static ApplicationViewModel Application => Get<ApplicationViewModel>();

        public static void Setup()
        {
          // Bind all required view models
            BindViewModels();
        }


        private static void BindViewModels()
        {
            Kernel.Bind<IDataProvider>().ToConstant(new DataProvider());

            Kernel.Bind<MainViewModel>().ToConstant(new MainViewModel(Kernel));

            Kernel.Bind<SettingsVM>().ToConstant(new SettingsVM(Kernel));

            Kernel.Bind<ApplicationViewModel>().ToConstant(new ApplicationViewModel());
        }

        public static SettingsVM GetSettings => Get<SettingsVM>();

        public static T Get<T>() => Kernel.Get<T>();
    }



 <materialDesign:Flipper
                MaxWidth="800"
                DataContext="{Binding Source={x:Static ioc:Ioc.GetSettings}}"
                Style="{StaticResource MaterialDesignCardFlipper}">
20 фев 19, 09:37    [21815134]     Ответить | Цитировать Сообщить модератору
Все форумы / WPF, Silverlight Ответить