[英]How to create WPF user control: custom TabItem?
Thanks in advance for any support! 预先感谢您的支持! I am trying to create a custom tab item to act as a canvas for dynamically creating UI elements.
我正在尝试创建一个自定义选项卡项,以充当动态创建UI元素的画布。 Here is an image to give an idea as to what I would like in this custom control:
这是一张有关此自定义控件中所需内容的图片:
I need to be able to generate the Tab Items dynamically to the TabControl in a parent form - the problem is that my code seems to do nothing to the TabItem - it's just always blank and it doesn't complain about my code. 我需要能够以父级形式动态生成TabControl的Tab项-问题是我的代码似乎对TabItem没有任何作用-它始终是空白的,并且不会抱怨我的代码。 What's missing?
缺少了什么? Thanks for any help!
谢谢你的帮助!
My WPF user control tabitem Code: 我的WPF用户控件Tabitem代码:
<UserControl x:Class="Configuration_Manager.SearchTab"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Configuration_Manager"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<TabItem Header="Search Configuration Name">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<GroupBox Header="Git Repo Credentials:">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Server Address:" />
<TextBox Grid.Column="1" Margin="2" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Username:" />
<TextBox Grid.Column="1" Margin="2" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Password:" />
<TextBox Grid.Column="1" Margin="2" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="CheckBoxStoreCredentials" Content="Store Credentials" Grid.Column="0" IsChecked="False" VerticalAlignment="Center"/>
<Button x:Name="ButtonDownloadConfiguration" Content="Download Configuration" Grid.Column="2" Margin="5" />
</Grid>
</StackPanel>
</GroupBox>
</Grid>
</StackPanel>
</TabItem>
</UserControl>
The Designer: 设计师:
In WPF if you want to dynamically create controls you always have to use templates. 在WPF中,如果要动态创建控件,则必须始终使用模板。
TabControl
is an ItemsControl
. TabControl
是ItemsControl
。 TabItem
elements (the tabs) are automatically generated for each item inside the ItemsControl.ItemsSource
collection. TabItem
元素(选项卡)是为ItemsControl.ItemsSource
集合内的每个项目自动生成的。 The visual of this TabItem
can be designed by using styles and templates. 可以使用样式和模板来设计此
TabItem
的外观。
Use the TabControl.ContentTemplate
property to specify the DataTemplate
for the content of each tab 使用
TabControl.ContentTemplate
属性为每个选项卡的内容指定DataTemplate
First you have to create the data model that should be displayed inside a TabItem
. 首先,您必须创建应在
TabItem
内部显示的数据模型。
TabData.cs: TabData.cs:
public class TabData : INotifyPropertyChanged
{
public TabData(string header)
{
this.Header = header;
}
public string Header { get; set; }
private string serverAddress;
public string ServerAddress
{
get => this.serverAddress;
set
{
if (value == this.serverAddress) return;
this.serverAddress = value;
OnPropertyChanged();
}
}
private string username;
public string Username
{
get => this.username;
set
{
if (value == this.username) return;
this.username = value;
OnPropertyChanged();
}
}
private string password;
public string Password
{
get => this.password;
set
{
if (value == this.password) return;
this.password = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then create a view model that handles the tab data and exposes the items source for the TabControl
. 然后创建一个处理选项卡数据的视图模型,并公开
TabControl
的项目源。
The view model is the DataContext
of the TabControl
. 视图模型是
TabControl
的DataContext
。
ViewModel.cs ViewModel.cs
public class ViewModel: INotifyPropertyChanged
{
public ViewModel()
{
this.TabDatas = new ObservableCollection<TabData>()
{
new TabData("First Tab"),
new TabData("Second Tab"),
new TabData("Third Tab")
};
}
// Adding a new TabData item to the TabDatas collection
// will dynamically create a new TabItem inside the TabControl
public void AddNewTab()
{
this.TabDatas.Add(new TabData("Fourth Tab"));
}
public ObservableCollection<TabData> TabDatas { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
AddNewTab
can be invoked from a ICommand
(eg on button clicked) or some event (eg new data available). 可以从
ICommand
(例如单击按钮)或某个事件(例如可用的新数据)中调用AddNewTab
。
MainWindow.xaml: MainWindow.xaml:
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<Grid>
<!-- Use DisplayMemberPath property to set the source property for the tab header -->
<TabControl x:Name="TabControl"
ItemsSource="{Binding TabDatas}"
DisplayMemberPath="Header" >
<!-- Use a DataTemplate to design the visual appearance of the TabItem content -->
<TabControl.ContentTemplate>
<DataTemplate DataType="TabData">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<GroupBox Header="Git Repo Credentials:">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Content="Server Address:" />
<TextBox Grid.Column="1"
Margin="2"
Text="{Binding ServerAddress}" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Content="Username:" />
<TextBox Grid.Column="1"
Margin="2"
Text="{Binding Username}"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Content="Password:" />
<TextBox Grid.Column="1"
Margin="2"
Text="{Binding Password}"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="CheckBoxStoreCredentials"
Content="Store Credentials"
Grid.Column="0"
IsChecked="False"
VerticalAlignment="Center" />
<Button x:Name="ButtonDownloadConfiguration"
Content="Download Configuration"
Grid.Column="2"
Margin="5" />
</Grid>
</StackPanel>
</GroupBox>
</Grid>
</StackPanel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.