简体   繁体   English

将 TabItems 添加到现有 TabControl WPF/MVVM

[英]Add TabItems to an existing TabControl WPF/MVVM

I have TabControl that has already define some TabItems on XAML .我有TabControl已经在XAML上定义了一些TabItems I need to create new TabItems and add to it.我需要创建新的TabItems并添加到其中。

If I use ItemSource I get an exception Items collection must be empty before using ItemsSource.如果我使用ItemSource我会得到一个异常Items collection must be empty before using ItemsSource.

The solution I have found so far is to create those TabItems I have already defined on XAML but programmatically on the ViewModel, so I can created the others I really need, but doesn't seems to be a good solution.到目前为止,我已经找到了解决办法就是创建这些TabItems我已经定义XAML ,但编程上的视图模型,这样我就可以建立我真的需要别人,但并不似乎是一个很好的解决方案。

Other solution would be to add the TabControl as a property and use the Code-Behind to bind it to the ViewModel, which I would like to avoid.其他解决方案是将TabControl添加为属性并使用代码隐藏将其绑定到 ViewModel,我想避免这种情况。

So, I'm just wondering if there is a way to do this only with XAML and MVVM.所以,我只是想知道是否有办法只使用XAML和 MVVM 来做到这一点。

Edit:编辑:

ItemSource attempt, which is working. ItemSource 尝试,这是有效的。

XAML: XAML:

<TabControl Grid.Row="1"
        Grid.Column="0"
        VerticalAlignment="Stretch"
        BorderThickness="0.5"
        BorderBrush="Black"
        ItemsSource="{Binding Model.TabItems, Mode=TwoWay}">
    <!--<TabControl.Items>
    </TabControl.Items>-->
</TabControl>

Model模型

public ObservableCollection<TabItem> TabItems {get;set;}

VM虚拟机

TabItem tabItem = new TabItem { Content = new DetailedViewModel((MyObject)inCommandParameter) };
Model.TabItems.Add(tabItem);

What you are doing here is NOT MvvM.你在这里做的不是MvvM。 Idea behind it is to keep parts of the app separate, ie Model should NOT return any UI elements.它背后的想法是将应用程序的各个部分分开,即模型不应返回任何 UI 元素。 If you want to use this with any other UI framework for example WinForms then it will fail and will require additional work.如果您想将它与任何其他 UI 框架(例如WinForms那么它将失败并且需要额外的工作。
What you need is something like this, bear in mind that this is an example and you will need to modify this to comply with your requirements.您需要的是这样的东西,请记住,这是一个示例,您需要对其进行修改以符合您的要求。
Model class:模型类:

namespace Model
{
    public class Profile
    {
        public string Name { get; set; }

        public static int I { get; set; } = 2;
    }
}  

After this you will need the ViewModel:在此之后,您将需要 ViewModel:

namespace VM
{
    public class MainViewModel : BaseViewModel
    {
        public MainViewModel()
        {
            ProfilesCollection = new List<Profile>();
            for (int i = 0; i < 100; i++)
            {
                ProfilesCollection.Add(new Profile() {Name = $"Name {i}"});
            }
        }

        private List<Profile> profilesCollection;   

        public List<Profile> ProfilesCollection
        {
            get { return profilesCollection; }
            set { profilesCollection = value; OnPropertyChanged(); }
        }
    }
}  

Now we have base to work with.现在我们有了可以使用的基础。 After that I assume you know how to add the relevant references in your xaml, but this might be seen by other people so I will include it anyway.在那之后,我假设您知道如何在您的 xaml 中添加相关引用,但这可能会被其他人看到,因此无论如何我都会将其包含在内。
Here is a complete MainWindow.xaml:这是一个完整的 MainWindow.xaml:

<Window x:Class="SO_app.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:vm="clr-namespace:VM;assembly=VM"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:converter="clr-namespace:SO_app.Converters"
    xmlns:validation="clr-namespace:SO_app.Validation"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    xmlns:local="clr-namespace:SO_app"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:model="clr-namespace:Model;assembly=Model"//reference to my model
    mc:Ignorable="d"
    Title="MainWindow" Height="452.762" Width="525" Closing="Window_Closing">
<!-- d:DataContext="{d:DesignInstance Type=vm:MainViewModel, IsDesignTimeCreatable=True}" -->
<Window.Resources>
    <CollectionViewSource Source="{Binding ProfilesCollection}" x:Key="profiles"/> // this corresponds to our collection in VM
</Window.Resources>
<Window.DataContext>
    <vm:MainViewModel/>//Data Context of the Window
</Window.DataContext>

<Window.Background>
    <VisualBrush>
        <VisualBrush.Visual>
            <Rectangle Width="50" Height="50" Fill="ForestGreen"></Rectangle>
        </VisualBrush.Visual>
    </VisualBrush>
</Window.Background>
<TabControl>
    <TabControl.Resources>
        <DataTemplate DataType="{x:Type model:Profile}">//this data template will be used by the TabControl
            <Grid>
                <TextBlock Text="{Binding Name}"/>
            </Grid>
        </DataTemplate>
    </TabControl.Resources>
    <TabControl.ItemsSource>
        <CompositeCollection>
            <TabItem Header="First Item"/>
            <TabItem Header="SecondItem"/>
            <CollectionContainer Collection="{Binding Source={StaticResource profiles}}"/>
        </CompositeCollection>
    </TabControl.ItemsSource>
</TabControl>


If you want to add more items then just use Command which would be implemented in VM and just add profile to it and enjoy the show.如果您想添加更多项目,那么只需使用将在 VM 中实现的命令,然后向其中添加profile即可欣赏节目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM