0

В общем есть некоторый список:

    private ObservableCollection<SiteConfig> _sites;
public ObservableCollection&lt;SiteConfig&gt; Sites
{
    get =&gt; _sites;
    set =&gt; Set(ref _sites, value);
}

Он находится в основной MainWindnowVM и привязан к одному TabItem. Также есть другой TabItem для регистрации нового элемента в списке сайтов, который находится в другой NewSiteVM. Проблема в том, что не знаю как передать данный список из MainWindnowVM в NewSiteVM, чтобы добавить новую запись при срабатывании команды.

DataContext объявил вот так, не знаю данное объявление нарушает принципы MVVM, но мне было так удобнее, нежеле в XAML

    public MainWindow()
    {
        InitializeComponent();
        AllSitesTabItem.DataContext = new MainWindnowVM();
        CreateNewPasswordTabItem.DataContext = new NewSiteVM();
    }

AllSitesTabItem и CreateNewPasswordTabItem - имена TabItem-ов.

Была идея сделать данный список статичным, но думаю это быдет лишь костыль и не знаю можно ли будет потом его связать с DataGrid.

Вся разметка:

<Window x:Class="PWManager.MainWindow"
    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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"
    mc:Ignorable="d"
    Title="PasswordsManager" Height="600" Width="800">
<Grid>
&lt;TabControl x:Name=&quot;TabControl&quot; SelectedIndex=&quot;{Binding SelectedTabItem}&quot;&gt;
    &lt;TabItem x:Name=&quot;AllSitesTabItem&quot; Header=&quot;Мои пароли&quot;&gt;
        &lt;Grid&gt;

            &lt;Grid.RowDefinitions&gt;
                &lt;RowDefinition Height=&quot;0.85*&quot;/&gt;
                &lt;RowDefinition Height=&quot;0.15*&quot;/&gt;
            &lt;/Grid.RowDefinitions&gt;

            &lt;DataGrid Grid.Row=&quot;0&quot; AutoGenerateColumns=&quot;False&quot; 
                      Margin=&quot;10&quot; Padding=&quot;5&quot; ItemsSource=&quot;{Binding Path=Sites}&quot; 
                      IsReadOnly=&quot;True&quot;&gt;

                &lt;DataGrid.Columns&gt;
                    &lt;DataGridHyperlinkColumn Header=&quot;Название&quot; Binding=&quot;{Binding Path=SiteUsl}&quot; 
                                             ContentBinding=&quot;{Binding Path=SiteName}&quot;&gt;
                        &lt;DataGridHyperlinkColumn.ElementStyle&gt;
                            &lt;Style TargetType=&quot;TextBlock&quot;&gt;
                                &lt;EventSetter Event=&quot;Hyperlink.Click&quot; Handler=&quot;OnHyperlinkClick&quot;/&gt;
                            &lt;/Style&gt;    
                        &lt;/DataGridHyperlinkColumn.ElementStyle&gt;
                    &lt;/DataGridHyperlinkColumn&gt;
                    &lt;DataGridTextColumn Header=&quot;Дата регистрации&quot; Binding=&quot;{Binding Path=RegisteDate}&quot;/&gt;
                &lt;/DataGrid.Columns&gt;

                &lt;DataGrid.RowDetailsTemplate&gt;
                    &lt;DataTemplate&gt;
                        &lt;StackPanel Orientation=&quot;Horizontal&quot; Margin=&quot;10&quot;&gt;
                            &lt;TextBlock Text=&quot;Пароль: &quot;/&gt;
                            &lt;TextBlock Text=&quot;{Binding Path=SitePassword}&quot; Margin=&quot;0, 0, 10, 0&quot;/&gt;
                            &lt;TextBlock Text=&quot;Последнее изменение: &quot;/&gt;
                            &lt;TextBlock Text=&quot;{Binding Path=DateLastChange}&quot;/&gt;
                        &lt;/StackPanel&gt;
                    &lt;/DataTemplate&gt;
                &lt;/DataGrid.RowDetailsTemplate&gt;

            &lt;/DataGrid&gt;

                &lt;Button Grid.Row=&quot;1&quot; Content=&quot;Создать новый пароль&quot; 
                    Height=&quot;50&quot; Margin=&quot;10&quot; Command=&quot;{Binding Path=NewSiteClick}&quot;/&gt;
        &lt;/Grid&gt;

    &lt;/TabItem&gt;
    &lt;TabItem x:Name=&quot;CreateNewPasswordTabItem&quot; Header=&quot;Новый пароль&quot;&gt;

        &lt;StackPanel Orientation=&quot;Vertical&quot; Margin=&quot;10&quot;&gt;
            &lt;TextBlock Text=&quot;Название Сайта&quot; Margin=&quot;10, 20, 0, 15&quot; FontSize=&quot;17&quot;/&gt;
            &lt;TextBox Margin=&quot;10, 0, 10, 0&quot; Text=&quot;{Binding Path=SiteName}&quot;/&gt;

            &lt;TextBlock Text=&quot;Пароль&quot; Margin=&quot;10, 15, 0, 15&quot; FontSize=&quot;17&quot;/&gt;
            &lt;TextBox Margin=&quot;10, 0, 10, 0&quot; Text=&quot;{Binding Path=Password}&quot;/&gt;

            &lt;TextBlock Text=&quot;Повторно пароль&quot; Margin=&quot;10, 15, 0, 15&quot; FontSize=&quot;17&quot;/&gt;
            &lt;TextBox Margin=&quot;10, 0, 10, 0&quot; Text=&quot;{Binding Path=PasswordAgain}&quot;/&gt;
            &lt;TextBlock Text=&quot;&quot; Margin=&quot;10&quot;/&gt;

            &lt;TextBlock Text=&quot;Ссылка на сайт&quot; Margin=&quot;10, 15, 0, 15&quot; FontSize=&quot;17&quot;/&gt;
            &lt;TextBox Margin=&quot;10, 0, 10, 20&quot; Text=&quot;{Binding Path=Uri}&quot;/&gt;

            &lt;Button Content=&quot;Добавить&quot; Margin=&quot;10&quot; Height=&quot;50&quot;
                Command=&quot;{Binding Path=NewSiteClick}&quot; /&gt;

        &lt;/StackPanel&gt;

    &lt;/TabItem&gt;
&lt;/TabControl&gt;

</Grid>

Tura
  • 1
  • У вас нет MVVM вообще. Привязки, и чистый WPF, все. Ну а про вопрос - я вам уже говорил в предыдущем, вы сказали "я знаю", но видимо нет... Показываю: class NewSiteVM { private readonly MainWindnowVM _mainVM; public NewSiteVM(MainWindnowVM mainVM) => _mainVM = mainVM; } далее ... = NewSiteVM(this);. Поздравляю, вы передали через конструктор ссылку одного класса на другой, теперь вы можете без труда в классе NewSiteVM получить доступ к объектам главного класса, например, _mainVM.Sites. – EvgeniyZ Jul 16 '23 at 22:50
  • На счет вопроса понял и наконец смог, спасибо. На счет MVVM хотел дополнительно спросить. Я его учу по видео с ютуба и там так описывается вся структура, скорее всего плейлист плохой. Можете посоветовать статьи, курсы по теме MVVM чтобы далее не задавал такие нелепые вопросы – Tura Jul 16 '23 at 23:14
  • Советовать что либо не буду, лишь скажу - не смотрите русскоязычных ютуберов, увы и ах, говорят ересь. Зарубежные, без проблем, там много отличного контента, но у нас.. Единицы. Ну а так, поймите саму суть MVVM, зачем вообще этот подход, а затем просто следуйте ему. – EvgeniyZ Jul 16 '23 at 23:21
  • Вот что такое MVVM? Это деление всего на мало связанные слои, где M слой не знает ничего про VM и V, а V не знает ничего про M и VM. Ключевое тут "мало связанные", ну а вы делаете например AllSitesTabItem.DataContext = new MainWindnowVM();, где окно (V слой) вдруг знает про VM и отвечает за него. Также OnHyperlinkClick - это должна быть команда, а значит сейчас у вас за логику отвечает View слой, когда должен отвечать VM, а еще лучше M. В общем, уберите все x:Name и пишите код так, чтоб UI был в одном месте, а логика в другом и их ничего не связывало, будет вам MVVM. – EvgeniyZ Jul 16 '23 at 23:22
  • Вкладки помню писал однажды, почитайте ответ, думаю будет полезно. – EvgeniyZ Jul 16 '23 at 23:23
  • Спасибо большое Вам. По-настоящему хороший человек. Всего Вам хорошего – Tura Jul 16 '23 at 23:31
  • На будущее, не стесняйтесь спрашивать, не стесняйтесь узнавать, не стесняйтесь доводить до конца свои вопросы, не стесняйтесь в конце концов своих пробелов в познаниях, это нормально! Вот вы задали сейчас по сути дубликат своего предыдущего вопроса, когда могли там сразу сказать "извините, не знаю как передать через конструктор". Так что, удачи в обучении! – EvgeniyZ Jul 17 '23 at 00:08
  • Имхо, но передавать VM в VM такое себе. Команду должна исполнять М? Первый раз слышу. – OwDafuq Jul 17 '23 at 06:29
  • @OwDafuq Чтож плохого в передаче VM в VM? Такой трюк часто используется например в переключении страниц, где в главной VM у нас есть условный PageVM CurrentPage {get; set;}, а в нужных страницах делаем mainVM.CurrentPage = ...;. Да, если идти глубже, проект больше, то там уже пишется все по принципам IoC, используют контейнеры, делают сервисы, но чистый WPF проект, без всего этого, да еще и для обучения, почему и нет? – EvgeniyZ Jul 17 '23 at 09:40
  • @OwDafuq Команду должна исполнять М? - Внимательно прочитайте что я написал, я говорил про логику, а не конкретно команду. Вот у нас в команде логика получения данных из базы, где ей место? В VM или всеж M? Я думаю должна быть своя M, которую мы вызываем в команде, которая находится в VM. Об этом я и писал выше. Так что, как по мне, ваш комментарий весьма странный... – EvgeniyZ Jul 17 '23 at 09:41
  • Переключение страниц через установку в какой-то VM... За это должен отвечать отдельный сервис, разве нет?
  • Логика получения данных - сервис/репозиторий/что угодно, но не модель данных точно, обычно отдается сервис в VM, который и отдает вам нужные М. В данном случае сервис/репозиторий/etc. не будет М, а будет просто зависимостью.
  • Да, чистый WPF круто, конечно, но как только у вас появляется чуть больше чем 2-3 страницы и больше 1-2 сервисов в приложении, то это уже становится не удобно и не поддерживаемо, поэтому мой совет сразу в пару к WPF изучать и Prism.
  • – OwDafuq Jul 17 '23 at 11:02
  • И, если уж так хочется передать MainVM, чтобы управлять страницами, то ИМХО, но лучше организовать это в сервис, который будет принимать в себя только название страницы, а внутри уже будет устанавливать нужную страницу сам, за это не должна отвечать отдельно взятая страница как по мне. Тот же Prism такое и делает, когда для переключения страниц предоставляет только регион и сервис для переключения страниц. – OwDafuq Jul 17 '23 at 11:04
  • @OwDafuq И опять-же вы полезли в дебри. Человек делает себе банальный "ТУДУ" для изучения, а вы ему призм, сервисы, и прочее... Вы путаете голый MVVM с MVVM + сервисы + контейнер. Я согласен, что с полноценном, здоровом проекте, логику контента лучше выносить в отдельный класс, но на простых проектах, это лишний гемор, лишний код, который только запутает. Ну а понять всякие призмы, когда будет знание об MVVM труда не составит. Ну, не мне тут конечно судить, автор пусть изучает все что хочет. – EvgeniyZ Jul 17 '23 at 13:37
  • Опять же имхо, но пройдя весь этот путь - лучше бы я сразу изучал как правильно делать, контейнеры, Prism и прочее, а не делал бы проекты не пойми как) – OwDafuq Jul 18 '23 at 07:55