C# ve,我希望上述视图放置在Voltage选项卡中,一旦用户从列表框中单击Voltage项,就会创建该选项卡。
TabControl具有ItemsSource属性。。这可以绑定到ViewModel中的可观察对象集合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
<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组件:)