我试图找到一种方法,在不创建新选项卡的情况下,使用TabControl将内容添加到选项卡页。我有一个ViewModel,它保存选项卡头和选项卡内容的值。当前,当单击“add tab”按钮时,它将添加一个带有正确标题的新选项卡,但是选项卡内容将丢失数据。我理解为什么我的工作不工作,这就是为什么我想知道是否有可能将这两个过程分开。我是新来的WPF,并将感谢任何帮助。
XAML:
<TabControl ItemsSource="{Binding}" Grid.Column="1" Grid.Row="1" Grid.RowSpan="5">
<TabControl.ItemTemplate>
<DataTemplate DataType="local:MyTab">
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="local:MyTab">
<StackPanel>
<TextBlock Text="First Name:" />
<TextBlock Binding="{Binding FirstName}" Margin="0,0,0,10"/>
<TextBlock Text="Second Name:" />
<TextBlock Binding="{Binding SecondName}" Margin="0,0,0,10"/>
<TextBlock Text="ID Number:" />
<TextBlock Binding="{Binding Id}" Margin="0,0,0,10"/>
<TextBlock Text="Age:" />
<TextBlock Binding="{Binding Age}" Margin="0,0,0,10"/>
<TextBlock Text="Gender:" />
<TextBlock Binding="{Binding Gender}" Margin="0,0,0,10"/>
<TextBlock Text="Address:" />
<TextBlock Binding="{Binding Address}" Margin="0,0,0,10"/>
</StackPanel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>C#:
public partial class MainWindow : Window
{
ObservableCollection<MyTab> tabs = new ObservableCollection<MyTab>();
string firstName;
string secondName;
string id;
int age;
string gender;
string address;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
firstName = firstNameTxtBox.Text;
secondName = surnameTxtBox.Text;
var tab = new MyTab() { Header = firstName + " " + secondName };
tabs.Add(tab);
DataContext = tabs;
firstNameTxtBox.Clear();
surnameTxtBox.Clear();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
id = idTxtBox.Text;
age = Convert.ToInt32(ageTxtBox.Text);
gender = genderTxtBox.Text;
address = addressTxtBox.Text;
var tab = new MyTab();
tab.Data.Add(new MyTabData() { FirstName = firstName, SecondName = secondName, Id = id, Age = age, Gender = gender, Address = address });
tabs.Add(tab);
DataContext = tabs;
idTxtBox.Clear();
ageTxtBox.Clear();
genderTxtBox.Clear();
addressTxtBox.Clear();
}
}发布于 2022-10-30 19:28:54
据我所知,MyTab是您的类,如下所示:
public class MyTab : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null)
{
if (object.Equals(variable, valeur)) return false;
variable = valeur;
NotifyPropertyChanged(nomPropriete);
return true;
}
private string name = "";
public string Name
{
get { return this.name; }
set
{
if (value != null && this.name != value)
{
this.name = value;
this.NotifyPropertyChanged("Name");
}
}
}
private string surname = "";
public string Surname
{
get { return this.surname; }
set
{
if (value != null && this.surname != value)
{
this.surname = value;
this.NotifyPropertyChanged("Surname");
}
}
}
// firsName, Id and so on...
public MyTab()
{
}
}首先,您的类必须是INotifyPropertyChanged,这样TextBoxes的绑定才能工作。
然后你的MainWindows :窗口,INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
private ObservableCollection<MyTab> listMyTab { get; set; } = new ObservableCollection<MyTab>();
public ObservableCollection<MyTab> ListMyTab { get { return this.listMyTab; } set { this.listMyTab = value; this.NotifyPropertyChanged("ListMyTab"); } }
public MainWindow()
{
InitializeComponent();
this.DataContext=this;
}您必须设置dataContext (如果要正确地执行它(MVVM),可以在一个名为ViewModelMainWindows.cs的不同文件中设置上下文。
ViewModel部分:
private ObservableCollection<MyTab> listMyTab { get; set; } = new ObservableCollection<MyTab>();
public ObservableCollection<MyTab> ListMyTab { get { return this.listMyTab; } set { this.listMyTab = value; this.NotifyPropertyChanged("ListMyTab"); } }那么xaml看起来是这样的:
<TabControl ItemsSource="{Binding ListMyTab}" Grid.Column="1" Grid.Row="1" Grid.RowSpan="5">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Label Grid.Column="1" Content="{Binding FirstName}" Margin="3" />
</Grid>
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="local:MyTab">
<StackPanel>
<Label Content="First Name:" />
<TextBlock Binding="{Binding FirstName}" Margin="0,0,0,10"/>
<Label Content="Second Name:" />
<TextBlock Binding="{Binding SecondName}" Margin="0,0,0,10"/>
<Label Content="ID Number:" />
<TextBlock Binding="{Binding Id}" Margin="0,0,0,10"/>
<Label Content="Age:" />
<TextBlock Binding="{Binding Age}" Margin="0,0,0,10"/>
<Label Content="Gender:" />
<TextBlock Binding="{Binding Gender}" Margin="0,0,0,10"/>
<Label Content="Address:" />
<TextBlock Binding="{Binding Address}" Margin="0,0,0,10"/>
</StackPanel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>TabControl的内容链接到ListMyTab (每个对象MyTab有一个TabItem )。然后将每个TabItem的内容绑定到每个项。因此,当您在TextBlock中编辑TextBlock(我会使用TextBox )时,标题将自动更新(这是绑定功能)。
如果要添加新项,请在某个地方添加一个按钮,如下所示:
private void Button_Add_Click(object sender, RoutedEventArgs e)
{
this.ListMyTab.Add(new MyTab());//add default values if necessary
}它将在可观察的集合中添加一个项,然后将出现一个新的选项卡。
此外,对于您的标签外观,我建议您看看:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>https://stackoverflow.com/questions/74255609
复制相似问题