在运行时动态更新 TabControl 内容

2024-04-09

所以这就是问题所在。我有一个窗口分为三个面板。中间包含绘图表面,左侧包含选项卡控件。选项卡控件的选项卡由一系列按钮组成,这些按钮必须在右侧面板中打开新菜单。我不知道如何在代码中执行此操作,因此我求助于在运行时在 C# 中单独创建每个按钮。看来必须有更好的方法来解决这个问题。我目前为按钮单击事件调用以下函数,以在运行时在名为“tabctrl”右面板的 TabControl 中绘制不同的菜单。它需要一个字符串参数来指定要绘制的一组菜单,尽管此时我只为其中一个菜单编写了代码。下面是该函数的代码和 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;

好吧,让我们来看看:

首先,你必须学会​​以一种abstract way:

什么是 TabControl?

它是小部件列表的图形表示,其中用户一次可以拥有 1 个活动小部件。这些小部件具有标题(选项卡项文本)、可见性状态和启用/禁用状态。

什么是一堆堆叠按钮? (工具栏,如果你想这样称呼它)

它是用户可以在任何给定时间执行的操作列表的图形表示。这些操作有一个描述(按钮的内容),可能有一个关联的图标或图形图像,以及一个启用/禁用状态。

什么是上下文菜单或菜单?

与上面相同,它是用户可以执行的操作列表的图形表示。

我将如何在 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 并创建一个适当的 ViewModel 即可。DataTemplate对于每个。

正如您在此示例中所看到的,我绝不会在代码中创建或操作任何 UI 元素。这大大简化了所有代码,并有助于保持逻辑和 UI 之间的清晰分离。 您可以将相同的概念应用于 WPF 中的所有内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在运行时动态更新 TabControl 内容 的相关文章

  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • 线程睡眠和Windows服务

    我正在开发一个 Windows 服务 该服务存在一些问题Thread Sleep 所以我想我会尝试使用计时器 因为这个问题建议 在 Windows 服务中使用 Thread Sleep https stackoverflow com que
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 有没有办法禁用 .NET 标签的“双击复制”功能?

    这真的很烦人 我使用标签作为列表项用户控件的一部分 用户可以单击它来选择列表项 然后双击它来重命名它 但是 如果剪贴板中有名称 双击标签会将其替换为标签文本 我还检查了应用程序中的其他标签 双击它们也会将其复制到剪贴板 我没有在这个程序中编
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐