wpf 如何将文本框添加到 TabItem?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14363805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:04:44  来源:igfitidea点击:

How to add a TextBox to TabItem?

c#wpf

提问by user1447343

I'm trying to add a new TabItemto TabControleach time I click on a button and I have no problem with that. But I want a textbox inside each TabItem. How do I do that? I need to do that with code I suppose.

我想要一个新添加TabItemTabControl我每次点击一个按钮,我有没有问题。但我想在每个TabItem. 我怎么做?我需要用我想的代码来做到这一点。

TabItem newTab = new TabItem();
                newTab.Header = ncn.courseName;
                newTab.FontSize = 20;
                TextBox textbox = new TextBox();
                textbox.Width = 200;
                textbox.Height = 100;
                textbox.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                textbox.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                Grid grid = new Grid();
                grid.Children.Add(textbox);
                newTab.Content = grid;
                this.Courses.Items.Add(newTab);
                this.Courses.SelectedItem = newTab;

采纳答案by Mats Magnem

If you would like to use only code and not the MVVM pattern, this can be solved this way:

如果您只想使用代码而不是 MVVM 模式,可以通过以下方式解决:

private void button1_Click(object sender, RoutedEventArgs e)
{
    TabItem item = null;
    Grid grid = null;
    TextBox textbox = null;

    try
    {
        // Creating the TextBox
        textbox = new TextBox();
        textbox.Width = 200;
        textbox.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
        textbox.VerticalAlignment = System.Windows.VerticalAlignment.Top;

        // Creating the Grid (create Canvas or StackPanel or other panel here)
        grid = new Grid();
        grid.Children.Add(textbox);     // Add more controls

        item = new TabItem();
        item.Header = "Hello, this is the new tab item!";
        item.Content = grid;            // OR : Add a UserControl containing all controls you like, OR use a ContentTemplate

        MyTabControl.Items.Add(item);
        MyTabControl.SelectedItem = item;   // Setting focus to the new TabItem
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error creating the TabItem content! " + ex.Message);
    }
    finally
    {
        textbox = null;
        grid = null;
        item = null;
    }
}

That is solving it "the old way" by using code-behind.

那就是通过使用代码隐藏来解决它“旧方法”。

If you on the other want to use the WPF like it should, you can do like this. To simplify a bit, I am using the code-behind as DataContext. I would recommend using a class instead in the running code. I have also used the Cutton click event instead if using the Button Command.

如果你想像它应该的那样使用 WPF,你可以这样做。为了简化一点,我将代码隐藏用作 DataContext。我建议在运行代码中使用一个类。如果使用按钮命令,我也使用了 Cutton 单击事件。

First I create a "holder" class for the tab items, holding the data you need.

首先,我为选项卡项创建一个“holder”类,保存您需要的数据。

TabItemHolder.cs

TabItemHolder.cs

    public class TabItemHolder : DependencyObject, INotifyPropertyChanged
    {
        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(String), typeof(TabItemHolder), new UIPropertyMetadata());
        public String Header
        {
            get { return (String)GetValue(HeaderProperty); }
            set
            {
                SetValue(HeaderProperty, value);
                NotifyPropertyChanged("Header");
            }
        }

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(String), typeof(TabItemHolder), new UIPropertyMetadata());
        public String Text
        {
            get { return (String)GetValue(TextProperty); }
            set
            {
                SetValue(TextProperty, value);
                NotifyPropertyChanged("Text");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(String PropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

Then I have the model class, in this example the MainWindow.cs itself:

然后我有模型类,在这个例子中是 MainWindow.cs 本身:

MainWindow.cs

主窗口.cs

public partial class MainWindow : Window, INotifyPropertyChanged { public static readonly DependencyProperty SelectedTabProperty = DependencyProperty.Register("SelectedTab", typeof(TabItemHolder), typeof(MainWindow), new UIPropertyMetadata()); public TabItemHolder SelectedTab { get { return (TabItemHolder)GetValue(SelectedTabProperty); } set { SetValue(SelectedTabProperty, value); NotifyPropertyChanged("SelectedTab"); } }

公共部分类 MainWindow : Window, INotifyPropertyChanged { public static readonly DependencyProperty SelectedTabProperty = DependencyProperty.Register("SelectedTab", typeof(TabItemHolder), typeof(MainWindow), new UIPropertyMetadata()); 公共 TabItemHolder SelectedTab { get { return (TabItemHolder)GetValue(SelectedTabProperty); } set { SetValue(SelectedTabProperty, value); NotifyPropertyChanged("SelectedTab"); } }

public static readonly DependencyProperty TabsProperty = DependencyProperty.Register("Tabs", typeof(ObservableCollection<TabItemHolder>), typeof(MainWindow), new UIPropertyMetadata());
public ObservableCollection<TabItemHolder> Tabs
{
    get { return (ObservableCollection<TabItemHolder>)GetValue(TabsProperty); }
    set
    {
        SetValue(TabsProperty, value);
        NotifyPropertyChanged("Tabs");
    }
}

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    this.Tabs = new ObservableCollection<TabItemHolder>();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.Tabs.Add(new TabItemHolder() { Header = "Hello, this is the new tab item!", Text = "Dummy text for the textbox" });
    this.SelectedTab = this.Tabs[this.Tabs.Count - 1];
}

public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String PropertyName)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}

}

}

And finally, the XAML would be something like this.

最后,XAML 将是这样的。

MainWindow.xaml

主窗口.xaml

    <Grid x:Name="LayoutRoot">
        <TabControl x:Name="MyTabControl"
                    Margin="12,67,12,12"
                    ItemsSource="{Binding Tabs}"
                    SelectedItem="{Binding SelectedTab}">
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBox Text="{Binding Path=Text}"
                                 Width="200"
                                 HorizontalAlignment="Left"
                                 VerticalAlignment="Top" />
                    </Grid>
                </DataTemplate>
            </TabControl.ContentTemplate>
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Header}"/>
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>
        <Button Content="Button" Height="34" HorizontalAlignment="Left" Margin="19,12,0,0" Name="button1" VerticalAlignment="Top" Width="90" Click="button1_Click" />
    </Grid>

That would do the same trick in a different (and in my opinion better) way.

那将以不同的(在我看来更好)的方式做同样的把戏。

I hope that helps you.

我希望这对你有帮助。