Ломаю голову уже целую ночь и так не пришел к ответу;( Надеюсь, что вы мне поможете Приступим, имеется разметка (Фото приложил) для TabControl
Проблема в том, что при переходе на ViewModel возникли проблемы с табами, самый первый при запуске приложения отрабатывает нормально, а кнопки добавить и удалить табы не работают. Ранее было событие, которое добавляла, удаляла табы и их содержимое, а при переходе на View такого события нет.
private void MyTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
var pos = MyTabControl.SelectedIndex;
if (pos != 0 && pos == Tabs.Count - 1) //last tab
{
var tab = Tabs.Last();
ConvertPlusToNewTab(tab);
AddNewPlusButton();
}
}
}
Я пытался как мог, но событие так и не удалось мне написать. Посмотрите, пожалуйста, мой код, может кто сможет подсказать как мне быть и что нужно сделать. Спасибо!
public class TabControlViewModel : ObservableRecipient{
public TabControlViewModel()
{
var tab1 = new TabVM()
{
Header = $"Новая вкладка",
Content = new ContentVM(new Frame(), new CompletionPage()),
};
Tabs.Add(tab1);
AddNewPlusButton();
}
private ObservableCollection<TabVM> tabs = new();
public ObservableCollection<TabVM> Tabs
{
get => tabs;
set => SetProperty(ref tabs, value);
}
private string? _header;
public string? Header
{
get => _header;
set => SetProperty(ref _header, value);
}
private int _tabSelectedItem;
public int TabSelectedItem
{
get => _tabSelectedItem;
set => SetProperty(ref _tabSelectedItem, value);
}
private int _tabSelectedIndex;
public int TabSelectedIndex
{
get => _tabSelectedIndex;
set => SetProperty(ref _tabSelectedIndex, value);
}
public void SelectionChanged()
{
if (TabSelectedIndex != 0 && TabSelectedIndex == Tabs.Count - 1) //last tab
{
var tab = Tabs.Last();
ConvertPlusToNewTab(tab);
AddNewPlusButton();
}
}
public ICommand MyTabControl_Button => new RelayCommand(OnTabCloseClick);
public void AddNewPlusButton()
{
var plusTab = new TabVM()
{
Header = "+",
IsPlaceholder = true
};
Tabs.Add(plusTab);
}
public void ConvertPlusToNewTab(TabVM tab)
{
//Do things to make it a new tab.
tab.Header = $"Новая вкладка";
tab.IsPlaceholder = false;
tab.Content = new ContentVM(new Frame(), new CompletionPage());
}
private void OnTabCloseClick()
{
if (Tabs.Count > 1)
{
if (TabSelectedItem == Tabs.Count - 2)//last tab before [+]
{
TabSelectedIndex--;
}
Tabs.RemoveAt(TabSelectedItem);
}
}
public class TabVM : ObservableRecipient
{
string _header;
public string Header
{
get => _header;
set => SetProperty(ref _header, value);
}
bool _IsPlaceholder = false;
public bool IsPlaceholder
{
get => _IsPlaceholder;
set => SetProperty(ref _IsPlaceholder, value);
}
ContentVM _Content = null;
public ContentVM Content
{
get => _Content;
set => SetProperty(ref _Content, value);
}
}
public class ContentVM
{
public ContentVM(Frame frame, CompletionPage completionPage)
{
CompletionPage = completionPage;
Frame = frame;
}
public CompletionPage CompletionPage { get; set; }
public Frame Frame { get; set; }
}}

MyTabControl_SelectionChanged- это UI событие, которое вдруг вызывает VM методыConvertPlusToNewTabиAddNewPlusButton, то есть у вас View знает про VM, а это не правильно, это нарушение. Ну а вообще, этот вопрос дубликат: https://ru.stackoverflow.com/a/1090412/220553 – EvgeniyZ Sep 23 '23 at 09:18x:Typeчуть сложнее, ибо повторю, V не должна ничего знать про другие слои, а значит нам нужна абстракция над VM, можно даже интерфейс, который уже и будет указан как тип. Ну а конвертор - вы не должны хотеть конвертировать в UI VM слой в что-то другое, ваша VM'ка должна дать конкретные данные, которые уже можно через конвертор перегонять, но не VM в конверторе. MVVM это про разделение всего на слои, чистый MVVM, это когда вы удалили все кроме V и проект запускается. – EvgeniyZ Sep 23 '23 at 14:28Action Close(), реализуем этот интерфейс у VM и вызываем тамInvoke(), а в V (окно), проверяем напримерDataContextна соответствие этому интерфейсу и задаемAction, готово, как видите, классы отвязаны, знают лишь про интерфейс, вот вам MVVM – EvgeniyZ Sep 23 '23 at 14:35Enum- начнем с того, что это всеж не VM, да и не M наверно, это ближе к интерфейсам наверно, хотя в разных проектах к ним относятся по разному. А так, эта задача решается без конвертора, при помощи триггеров, чистый XAML. – EvgeniyZ Sep 23 '23 at 16:23... ViewModel { get; }в классе окна (V), это нарушение MVVM, но удобно, я оставил, использую. – EvgeniyZ Sep 23 '23 at 16:36