wpf 在TabControl中运行TabControl.ContentTemplate

monwx1rj  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(189)

我正在尝试使用TabControl寻找一种方法,在不创建新标签页的情况下向标签页添加内容。我有一个ViewModel,它保存了标签标题标签内容的值。目前,当单击“添加标签”按钮时,它将添加一个具有正确标题的新标签页。但是选项卡内容会丢失数据。我理解为什么我的工作不起作用,这就是为什么我想知道是否有可能将这两个进程分开。我是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();
        }
    }
dxxyhpgq

dxxyhpgq1#

据我所知,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,这样TextBox的绑定才能工作。
然后您的主窗口:窗口,INotify属性已更改

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中编辑FirstName时(我将使用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>

相关问题