C# 在运行时动态更新TabControl内容

C# 在运行时动态更新TabControl内容,c#,.net,wpf,C#,.net,Wpf,这就是问题所在。我有一扇分为三个面板的窗户。中间包含一个图形表面,左侧包含一个选项卡控件。tab控件的选项卡由一系列按钮组成,这些按钮必须在右侧面板中打开新菜单。我不知道如何在代码中实现这一点,所以我求助于在C#中的运行时分别创建每个按钮。看来应该有更好的办法来解决。目前,我为按钮点击事件调用了下面的函数,以便在运行时在名为“tabctrl”的TabControl右面板中绘制不同的菜单。它需要一个字符串参数来指定要绘制的菜单集,尽管在这一点上我只为菜单的一个部分编写了代码。下面是函数和xml的代

这就是问题所在。我有一扇分为三个面板的窗户。中间包含一个图形表面,左侧包含一个选项卡控件。tab控件的选项卡由一系列按钮组成,这些按钮必须在右侧面板中打开新菜单。我不知道如何在代码中实现这一点,所以我求助于在C#中的运行时分别创建每个按钮。看来应该有更好的办法来解决。目前,我为按钮点击事件调用了下面的函数,以便在运行时在名为“tabctrl”的TabControl右面板中绘制不同的菜单。它需要一个字符串参数来指定要绘制的菜单集,尽管在这一点上我只为菜单的一个部分编写了代码。下面是函数和xml的代码。有没有更好的办法

xml:

好的。。。让我们看看:

首先,你必须学会以一种抽象的方式思考你的用户界面:

什么是TabControl

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

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

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

什么是上下文菜单,还是菜单

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

我将如何在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);
            }
        }
    }
公共类选项卡ViewModel:ViewModelBase { 私人可观测收集项目; 公共可观测收集项目 { 获取{return\u items???(\u items=newobserveCollection());} } 私有视图模型库_selectedItem; 公共视图模型库SelectedItem { 获取{return\u selectedItem;} 设置 { _选择editem=值; NotifyPropertyChange(()=>SelectedItem); } } } 公共类选项卡ViewModel:ViewModelBase { 私有字符串\u标题; 公共字符串标题 { 获取{return\u title;} 设置 { _标题=价值; NotifyPropertyChange(()=>标题); } } 私人住宅已启用; 公共场所被禁止 { 获取{return} 设置 { _isEnabled=值; NotifyPropertyChange(()=>已启用); } } 私人住宅可见; 公共图书馆是可见的 { 获取{return\u isVisible;} 设置 { _isVisible=值; NotifyPropertyChange(()=>IsVisible); } } } 在本例中,TabControl中的每个项(TabItem)都将绑定到其中一个ViewModel,然后只需为每个选项卡继承基本TabViewModel,并为每个选项卡创建一个适当的
DataTemplate

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

如果您发布一个屏幕截图,展示您希望屏幕的样子,这会有所帮助。您是否使用MVVM light?因为我在这里看到一个基类-ViewModelBase@buba1947不是真的。我基本上是使用这里和那里的代码构建了自己的MVVM基类(
ViewModelBase,Command,Command,selective
,等等),谢谢。。。因为我从MVVM light开始,基类是defaultOh man的ViewModelBase。。。在我头顶上方一点。ATM我真的不理解你贴的大部分C#。。。我将温习一下类的语法和实现,然后再与您联系。谢谢你的提示answer@SteelNation这些是“简单、简单的属性和INotifyPropertyChanged”。这就是在WPF中开发的方式。NotifyPropertyChange(()=>PropertyName)语法只是
<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);
            }
        }
    }