Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / ViewModel c несколькими DataContext. / 3 сообщений из 3, страница 1 из 1
19.02.2019, 16:18
    #39776276
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ViewModel c несколькими DataContext.
Всем привет. Есть View, у которой есть ее DataContext (MainViewModel) и есть её часть, у которой должна быть своя ViewModel.
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
<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.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
  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-контейнер.


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
    /// <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
Код: xml
1.
2.
3.
    <materialDesign:Flipper.DataContext>
                    <vm:SettingsVM />
                </materialDesign:Flipper.DataContext>


используется дефолтный пустой конструктор без аргументов и соответственно внедрение зависимостей не работает (kernel=null) (для задания x:TypeArguments="vm:MainViewModel" - работает). Не хочу включать класс SettingsVM как свойство MainViewModel - хочу сделать их несвязанными. Как можно заставить инициализироваться SettingsVM через контейнер зависимостей? Спасибо
...
Рейтинг: 0 / 0
19.02.2019, 16:53
    #39776312
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ViewModel c несколькими DataContext.
Так диконтейнер же сам инициализирует все модели. Выставьте наружу у обертки диконтейнера статик-свойства, возвращающие нужные модели/сервисы, и подцепляйте их в разметке через x:Static.
P.S. Инициализировать потребителя инжектированных сущностей ядром диконтейнера идеологически неправильно, это прямая дорога к антипаттерну God, и мало чем отличается от сервис-локатора. По фэншую нужно инициализировать каждого потребителя только теми инжектированными классами, которые он использует.
...
Рейтинг: 0 / 0
20.02.2019, 09:37
    #39776578
vb_sub
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ViewModel c несколькими DataContext.
Сон Веры Павловны,
спасибо Ваш совет мне помог

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
    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>();
    }




Код: xml
1.
2.
3.
4.
 <materialDesign:Flipper
                MaxWidth="800"
                DataContext="{Binding Source={x:Static ioc:Ioc.GetSettings}}"
                Style="{StaticResource MaterialDesignCardFlipper}">
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / ViewModel c несколькими DataContext. / 3 сообщений из 3, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]