我是一名 WPF 程序员新手,因此需要一些简单任务的帮助。
1- 如图所示,我想要 (+) 选项卡(这是一个使用 TabItem 创建的选项卡,还是应该是按钮或其他东西?:-/)来创建一个左侧的选项卡,例如 (A1) ,再次按下,应该创建(A2),有点像在选项卡式浏览器中......并且如果可能的话,按下(-)会删除用户提示中选定的选项卡。
[外部图像不再可用]
2-我想要,用户在文本框中输入文本,内容用逗号或分号分隔,并且该内容在按钮按下/单击时添加到 COMBOBOX,我想,它需要某种数据绑定?不确定,..这样,到最后,文本框中的内容将成为组合框中的列表(按下按钮时)
如果可能,在文本框中选择文本时,单击按钮(选择将文本框内容添加到组合框的相同或不同按钮),它会从文本框和组合框中删除相同的内容。
数据绑定和 MVVM 使一切变得更容易。 一开始比较困难,但最终会容易得多。
创建两个类,
Item
和ItemCollection
,都实现INotifyPropertyChanged
。 Item
应公开字符串 Text
属性,而 ItemCollection
应公开 ObservableCollection<Item>
Items
属性和 Item
SelectedItem
属性。
使
ItemCollection
类的构造函数使用测试数据填充 Items
并设置 SelectedItem
。
在您真正开始实现选项卡控件之前,这似乎需要做很多事情,但是相信我,您会喜欢结果的。 TabControl 的 XAML 将如下所示:
<TabControl
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}">
<TabControl.DataContext>
<local:ItemsCollection/>
</TabControl.DataContext>
<TabControl.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<TextBlock Background="AliceBlue" Text="{Binding Text}"/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Style.Setters>
<Setter Property="Header" Value="{Binding Text}"/>
</Style.Setters>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
让我们了解一下它的作用。 它创建了一个
TabControl
。 它创建一个 ItemsCollection
对象并将其设置为 TabControl
的 DataContext
。 您已将 ItemSource
绑定到 Items
,因此 TabControl
将为每个项目创建一个 TabItem
。 它将把 ItemContainerStyle
应用于每个 TabItem
,从而将其 Header
属性设置为 Item
的 Text
属性。
当控件呈现选项卡的内容时,它会找到正在呈现的项目,搜索资源以找到
DataTemplate
(其 DataType
与该项目匹配),并使用该模板。 由于我们在 TabControl.Resources
中定义了一个,因此您会再次获得漂亮的蓝色背景和 Text
属性。
这似乎需要经历很多事情。 但现在您不必编写任何操作 UI 的代码;您只需编写操作您的
ItemsCollection
的代码,UI 就会自行处理。
现在让我们来添加新选项卡。 我们要做的是将一个新项目添加到控件中,当它被选中时,将一个新项目添加到
Items
集合中。
创建一个新类,名为,哦,
ControlItem
。 让它源自Item
。 修改您的 ItemsCollection
构造函数,使其添加的最后一项是 ControlItem
,而不是 Item
。 并将该项目的 Text
属性设置为“+”。
将此方法添加到
ItemsCollection
:
public Item AddItem()
{
Item newItem = new Item {Text = "New item"};
Items.Insert(Items.Count-1, newItem);
return newItem;
}
现在添加到窗口的代码隐藏中,并作为
SelectionChanged
的 TabControl
事件处理程序:
void TabControl_SelectionChanged(object sender, RoutedEventArgs e)
{
TabControl tc = (TabControl) sender;
if (tc.SelectedItem is ControlItem)
{
ItemsCollection ic = (ItemsCollection) tc.DataContext;
tc.SelectedItem = ic.AddItem();
}
}
您可以实现类似的逻辑来从列表中删除项目,但是您需要向
ItemsCollection
引入另一个变量来跟踪之前选择的项目,以便您知道要删除哪个项目。
您可以做的另一件事:在
Background
中实现 Item
属性,并向 ItemContainerStyle
添加一个 setter,将 TabItem
的 Background
属性绑定到它。 然后您可以在 ControlItem
中重载该属性,以便您的添加和删除选项卡看起来不同。
您还可以为控件项实现不同的子类,并让它们公开您在
SelectionChanged
事件处理程序中调用的方法。 这样,事件处理程序就不必知道所单击的控件项正在执行的操作。 事实上,如果您将该方法作为 Item
的一部分,并且让它不执行任何操作(除非它被重写),则窗口甚至不需要知道 Item
有 子类。
简而言之,这就是 MVVM 背后的哲学:将视图绑定到它几乎一无所知的对象。 让视图模型对象控制发生的事情,这样视图就不必这样做。
下一部分我可以提供更多帮助
<StackPanel>
<TextBox x:Name="txtOptions" TextChanged="OnTextChanged"></TextBox>
<ComboBox x:Name="cboSelect" ItemsSource="{Binding Path=Options}"/>
</StackPanel>
代码隐藏窗口(或您的类)必须实现 INotifyPropertyChanged。还将窗口的 DataContext 属性设置为其自身(例如在 ctor 中),如
this.DataContext = this;
public partial class Window1 : Window, INotifyPropertyChanged
{
string[] _options;
public string[] Options
{
get
{ return _options; }
set
{
_options = value;
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs("Options"));
}
}
文本更改事件处理程序修改隐藏代码上的选项属性,并触发该属性已被修改的通知。组合框会收到通知,因为它的数据绑定到该属性并会自我更新。
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
this.Options = txtOptions.Text.Split(';');
}