C# ve,我希望上述视图放置在Voltage选项卡中,一旦用户从列表框中单击Voltage项,就会创建该选项卡。

C# ve,我希望上述视图放置在Voltage选项卡中,一旦用户从列表框中单击Voltage项,就会创建该选项卡。,c#,wpf,mvvm,listbox,tabitem,C#,Wpf,Mvvm,Listbox,Tabitem,TabControl具有ItemsSource属性。。这可以绑定到ViewModel中的可观察对象集合 <Grid Grid.Row="0" > <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}"> <tablocal:CloseableTabItem He

TabControl具有ItemsSource属性。。这可以绑定到ViewModel中的可观察对象集合

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
除此之外,observable集合中使用的对象必须具有关联的DataTemplate,该DataTemplate应为TabItem

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
因此,当您使用DataTemplate向ObservaleCollection添加一个对象(该对象充当TabControl的源)时,会向TabControl添加一个新的TabItem

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
还要确保初始选项卡项的observablecollection中有一个条目/对象

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
通过添加适当的命名空间/引用,可以从DataTemplate中的其他项目中引用TabItem

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
这是ViewModel类

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
 public class TabItemDetail
{
    public string Header { get; set; }
}

public class MainWindowViewModel : INotifyPropertyChanged
{
    #region Members

    List<string> _dataSource = null;
    string _selectedDataSource = null;
    ObservableCollection<TabItemDetail> _tabItems = null;

    #endregion

    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    public ObservableCollection<TabItemDetail> Items
    {
        get
        {
            if (_tabItems == null)
            {
                _tabItems = GetTabItems();
            }

            return _tabItems;
        }
    }

    public List<string> DataSource
    {
        get
        {
            if (_dataSource == null)
            {
                _dataSource = GetDataSource();
            }

            return _dataSource;
        }
    }

    public string SelectedDataSource
    {
        get { return _selectedDataSource; }
        set
        {
            if (_selectedDataSource == value)
                return;

            _selectedDataSource = value;

            AddItemsToTab(value);

            OnPropertyChanged("SelectedDataSource");
        }
    }


    #region Private methods

    private void AddItemsToTab(string selectedItem)
    {
        if (_tabItems != null && _tabItems.Count > 0)
        {
            var query = from item in _tabItems
                        where item.Header == selectedItem
                        select item;

            if (query.Count() == 1)
                return;
            else
                _tabItems.Add(new TabItemDetail { Header = selectedItem });
        }
    }

    private List<string> GetDataSource()
    {
        List<string> source = new List<string>();

        source.Add("Default tab");
        source.Add("Voltage Tab");

        return source;
    }

    private ObservableCollection<TabItemDetail> GetTabItems()
    {
        ObservableCollection<TabItemDetail> newSource = new ObservableCollection<TabItemDetail>();
        newSource.Add(new TabItemDetail { Header = "Connect" });

        return newSource;
    }

    #endregion
}

tabcontrol的数据模板不应包含tabitem。tabcontrol正在为绑定集合中的每个元素生成一个tabitem。要启用tabitem标头的数据绑定,请设置tabcontrol的itemcontainerstyle属性。以下是一个小样本:

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
观点:

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
<Window x:Class="WpfLab.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.5*"/>
        <ColumnDefinition Width="0.5*"/>
    </Grid.ColumnDefinitions>
    <TabControl ItemsSource="{Binding ProductTabs}">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding Header}"/>
            </Style>
        </TabControl.ItemContainerStyle>
    </TabControl>
    <ListBox Grid.Column="1" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct}"/>
</Grid>

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
视图模型

                <Grid Grid.Row="0" >
                    <TabControl Name="ConnectTab" Style="{DynamicResource styleBackground}">
                        <tablocal:CloseableTabItem Header="Connect" x:Name="ConnectMain" MouseDoubleClick="TabItem_MouseDoubleClick"> 
                            <DockPanel>
                                <ListView  Name="listView" Height="460" Margin="0,-77,0,0" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct, Mode=TwoWay}">
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn Width="283" Header="Connection Status" DisplayMemberBinding="{Binding Connection_Status}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

                                <Button Content="Connect" Height="23" HorizontalAlignment="Stretch" Margin="-920,500,0,0" Name="ConnectBtnGrid" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=ConnectCommand}" />
                                <Button Content="Update MSP430" Height="23" HorizontalAlignment="Stretch" Margin="-560,500,0,0" Name="UpdateMSPBtn" VerticalAlignment="Stretch" Width="100" />
                                <Button Content="Disconnect" Height="23" HorizontalAlignment="Stretch" Margin="-220,500,0,0" Name="DisconnectBtn" VerticalAlignment="Stretch" Width="100" Command="{Binding Path=DisconnectCommand}" />
                            </DockPanel>
                       </tablocal:CloseableTabItem>
                    </TabControl>
                </Grid>                 
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace WpfLab
{
    public partial class MainWindow : Window
    {
        Product selectProduct;

        public MainWindow()
        {
            InitializeComponent();

            Products = new ObservableCollection<Product>();
            ProductTabs = new ObservableCollection<Product>();

            var products = Enumerable.Range(0, 10).Select(i => new Product { Header = "Product " + i });
            foreach (var p in products)
                Products.Add(p);

            DataContext = this;
        }

        public Product SelectedProduct 
        {
            get { return this.selectProduct; }

            set
            {
                UpdateTabs(this.selectProduct, value);
                this.selectProduct = value;
            }
        }

        public ObservableCollection<Product> Products { get; private set; }

        public ObservableCollection<Product> ProductTabs { get; private set; }

        void UpdateTabs(Product old, Product @new)
        {
            if (ProductTabs.Any(p => p == old))
                ProductTabs.Remove(old);

            ProductTabs.Add(@new);
        }
    }

    public class Product
    {
        public string Header { get; set; }

        public override string ToString()
        {
            return Header;
        }
    }
}
使用System.Collections.ObjectModel;
使用System.Linq;
使用System.Windows;
命名空间WpfLab
{
公共部分类主窗口:窗口
{
产品选择产品;
公共主窗口()
{
初始化组件();
产品=新的可观察收集();
ProductTabs=新的ObservableCollection();
var products=Enumerable.Range(0,10)。选择(i=>newproduct{Header=“Product”+i});
foreach(产品中的var p)
产品.加入(p);;
DataContext=this;
}
公共产品精选产品
{
获取{返回this.selectProduct;}
设置
{
更新选项卡(this.selectProduct,value);
this.selectProduct=value;
}
}
公共可观测集合产品{get;private set;}
public observeCollection ProductTabs{get;private set;}
无效更新选项卡(旧产品,新产品)
{
if(ProductTabs.Any(p=>p==old))
产品标签。删除(旧);
ProductTabs.Add(@new);
}
}
公共类产品
{
公共字符串头{get;set;}
公共重写字符串ToString()
{
返回头;
}
}
}

感谢Sandepku:)My voltage mainwindow.xaml有一些Ui组件。查看上面的代码,看起来可以动态添加选项卡,但如何在电压选项卡中显示Ui元素???如果查看上面代码中的onTabChnaged(),您会发现我可以从列表框中获取selecteditem。所以,当我从列表框中选择电压时,电压选项卡应该被添加到已经有连接项的tabcontrol中。查看您的示例代码,我可能需要更改类的整个结构。如果您愿意,我可以上传示例应用程序,以解决我面临的问题:)^:(我被这个问题困住了。你想让我编辑帖子并在这里添加viewmodel类和xaml吗???基本上我只需要更新xaml并将上面提到的类添加到我的项目中。我将保持viewmodel类与发布问题时的状态。我试过了。仍然不成功:(实际上,添加标签的想法需要在我在代码中完成的几个初始步骤之后完成。我相信,如果你仔细阅读我的几行代码,你将能够了解情况。如果你不介意的话,有没有办法我可以将sampple应用程序发送给你?这将非常有用,兄弟:(你不认为与产品相关的内容应该在产品视图模型中?我应该在哪里发布?)InitializeComponent();Products=new ObservableCollection();ProductTabs=new ObservableCollection();var Products=Enumerable.Range(0,10)。选择(i=>new Product{Header=“Product”+i});foreach(产品中的var p)products.Add(p);DataContext=this;绝对!这只是一个让您朝正确方向前进的示例。如果您需要更多帮助,请告诉我。谢谢per:)它添加了选项卡。但这不是我想要的解决方案。如果您注意到在我的示例应用程序中,我有一个选项卡,其中包含连接项,该项在启动时应可见,以便我可以将项目列表放入列表框中。基本上,我的默认选项卡项和列表框是绑定的。选中SaveExecuted()在我的viewmodel中,您将了解如何绑定我的listbox和tabitem组件:)