问题描述
我有TabControl
,已经在XAML
上定义了一些TabItems
.我需要创建新的TabItems
并将其添加到其中.
I have TabControl
that has already define some TabItems
on XAML
. I need to create new TabItems
and add to it.
如果我使用ItemSource
,我会得到一个异常Items collection must be empty before using ItemsSource.
If I use ItemSource
I get an exception Items collection must be empty before using ItemsSource.
到目前为止,我发现的解决方案是创建我已经在XAML
上定义但在ViewModel上以编程方式创建的那些TabItems
,因此我可以创建我真正需要的其他TabItems
,但这似乎不是一个好方法.解决方案.
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.
其他解决方案是将TabControl
添加为属性,并使用Code-Behind将其绑定到ViewModel,我想避免这种情况.
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.
所以,我只是想知道是否只有使用XAML
和MVVM才能做到这一点.
So, I'm just wondering if there is a way to do this only with XAML
and MVVM.
ItemSource尝试,正在工作.
ItemSource attempt, which is working.
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>
型号
public ObservableCollection<TabItem> TabItems {get;set;}
VM
TabItem tabItem = new TabItem { Content = new DetailedViewModel((MyObject)inCommandParameter) };
Model.TabItems.Add(tabItem);
推荐答案
您在这里所做的是不 MvvM.其背后的想法是将应用程序的各个部分分开,即模型不应返回任何UI元素.如果要将其与其他任何UI框架(例如WinForms
)一起使用,则它将失败,并且需要进行其他工作.
您需要的是这样的,请记住这是一个示例,您将需要对其进行修改以符合您的要求.
模型类别:
What you are doing here is NOT MvvM. Idea behind it is to keep parts of the app separate, i.e. Model should NOT return any UI elements. If you want to use this with any other UI framework for example WinForms
then it will fail and will require additional work.
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;
}
}
此后,您将需要ViewModel:
After this you will need the 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(); }
}
}
}
现在我们有合作基础.之后,我假设您知道如何在xaml中添加相关的引用,但是其他人可能会看到它,因此无论如何我都会将其包括在内.
这是完整的MainWindow.xaml:
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.
Here is a complete 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>
如果要添加更多项,则只需使用将在VM中实现的Command,然后向其中添加profile
并欣赏表演即可.
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.
这篇关于将TabItem添加到现有的TabControl WPF/MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!