所以这就是问题所在。我有一个窗口分为三个面板。中间包含一个绘图表面,左边包含一个制表符控件。选项卡控件的选项卡每个都包含一个按钮列表,这些按钮必须在右侧面板中打开新菜单。我无法弄清楚如何在代码中执行此操作,因此我使用C#在运行时单独创建每个按钮。似乎必须有更好的方法来实现它。我目前在按钮单击事件中调用以下函数,在运行时在TabControl中命名为“tabctrl”右侧面板中绘制不同的菜单。它需要一个字符串参数来指定要绘制的菜单集,尽管此时我只编写了一个菜单的代码。下面是函数和xml的代码。有没有更好的方法来解决这个问题?
的xml:
<TabControl DockPanel.Dock="Right" Background="White" x:Name="tabctrl">
<TabItem Height ="38" Name="Tab1" Header="tab3"/>
</TabControl>
C#:
private void menuOpen(string menuSelected)
{
//Logic statement for what menu is being opened
switch (menuSelected)
{
case "BackGround":
{
//Remove Current Tabs
//Initialize Tab Item, set title, and add tab item to tab control
TabItem BackGround = new TabItem();
BackGround.Header = "BackGround";
tabctrl.Items.Insert(1, BackGround);
BackGround.Height = 38;
//Initialize Stack Panel, set orientation, and add to tab control
StackPanel panel = new StackPanel();
panel.Orientation = Orientation.Vertical;
BackGround.Content = panel;
//Initialize Menu Items
Button AddMap = new Button();
Button AddDemoMap = new Button();
Button RemoveMap = new Button();
Button MoveSelected = new Button();
Button Properties = new Button();
Button ScaleBackground = new Button();
//Define Button Text
AddMap.Content = "Add Map";
AddDemoMap.Content = "Add Demo Map";
RemoveMap.Content = "Remove Map";
MoveSelected.Content = "Move Selected Map to Top of List";
Properties.Content = "Properties";
ScaleBackground.Content = "Scale Background to Pipes";
AddMap.Height = 50;
AddDemoMap.Height = 50;
RemoveMap.Height = 50;
MoveSelected.Height = 50;
Properties.Height = 50;
ScaleBackground.Height = 50;
//Add Buttons to StackPanel
panel.Children.Add(AddMap);
panel.Children.Add(AddDemoMap);
panel.Children.Add(RemoveMap);
panel.Children.Add(MoveSelected);
panel.Children.Add(Properties);
panel.Children.Add(ScaleBackground);
}
break;
答案 0 :(得分:6)
好的......让我们看看:
首先,您必须学会以抽象方式思考您的用户界面:
什么是TabControl?
它是小部件列表的图形表示,其中用户一次可以拥有1个活动小部件。这些小部件具有标题(标签项文本),可见性状态和启用/禁用状态。
什么是堆叠按钮? (工具栏,如果你想把它叫做那个)
它是用户在任何给定时间可以执行的操作列表的图形表示。这些操作具有描述(按钮的内容),可能是关联的图标或图形图像,以及启用/禁用状态。
什么是ContextMenu或菜单?
与上面相同,它是用户可以执行的操作列表的图形表示。
我如何在WPF中创建动态TabControl?
这是支持动态子项的WPF TabControl的XAML:
<Window x:Class="WpfApplication4.Window12"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window12" Height="300" Width="300">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
</Window.Resources>
<TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Setter Property="Header" Value="{Binding Title}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Window>
视图模型:
public class TabbedViewModel: ViewModelBase
{
private ObservableCollection<TabViewModel> _items;
public ObservableCollection<TabViewModel> Items
{
get { return _items ?? (_items = new ObservableCollection<TabViewModel>()); }
}
private ViewModelBase _selectedItem;
public ViewModelBase SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
NotifyPropertyChange(() => SelectedItem);
}
}
}
public class TabViewModel: ViewModelBase
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
NotifyPropertyChange(() => Title);
}
}
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
NotifyPropertyChange(() => IsEnabled);
}
}
private bool _isVisible;
public bool IsVisible
{
get { return _isVisible; }
set
{
_isVisible = value;
NotifyPropertyChange(() => IsVisible);
}
}
}
使用此示例,TabControl中的每个项目(TabItem)将绑定到其中一个ViewModel,然后只需继承每个选项卡的基本TabViewModel并为每个选项卡创建一个正确的DataTemplate
正如您在此示例中所看到的,我无法在代码中创建或操作任何UI元素。这简化了所有代码A LOT,并有助于在逻辑和UI之间保持清晰的分离。 您可以将相同的概念应用于WPF中的所有内容。