Wpf 使用组合框控制TabControl活动选项卡
我真正想要实现的是通过使用combobox作为导航控件来完全控制活动的TabItem 以下是我到目前为止得到的:Wpf 使用组合框控制TabControl活动选项卡,wpf,combobox,tabcontrol,Wpf,Combobox,Tabcontrol,我真正想要实现的是通过使用combobox作为导航控件来完全控制活动的TabItem 以下是我到目前为止得到的: <TabControl Canvas.Left="26" Canvas.Top="27" Height="100" Name="TabControl1" Width="220"> <TabItem Header="TabItem1" x:Name="TabItem1"> <Grid />
<TabControl Canvas.Left="26" Canvas.Top="27" Height="100" Name="TabControl1" Width="220">
<TabItem Header="TabItem1" x:Name="TabItem1">
<Grid />
</TabItem>
<TabItem Header="TabItem2" x:Name="TabItem2">
<Grid />
</TabItem>
</TabControl>
<ComboBox Canvas.Left="126" Canvas.Top="134" Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items}"
SelectedValue="{Binding ElementName=TabControl1, Path=SelectedIndex}"
SelectedValuePath="TabIndex"
DisplayMemberPath="Header"/>
但真正有效的还是当我按下组合框的togglebutton时显示的列表。
即使通过列表选择tabitem名称也没有任何作用,它甚至不会更新combobox的selected value文本框
有什么帮助吗
编辑:
史蒂夫·罗宾斯的回答在“控制”问题上很有效
在combobox下拉列表中选择项目不会更新combobox的值,这一事实又如何呢?(组合框文本框仍然为空!!)如果您试图从组合框中控制TabControl,那么在我看来它有点落后。。如果更改tab控件上的SelectedIndex以将其绑定到combo,则应该可以:
<TabControl Canvas.Left="26" Canvas.Top="27" Height="100" Name="TabControl1" Width="220" SelectedIndex="{Binding ElementName=CmbTabs, Path=SelectedIndex}">
<TabItem Header="TabItem1" x:Name="TabItem1">
<Grid />
</TabItem>
<TabItem Header="TabItem2" x:Name="TabItem2">
<Grid />
</TabItem>
</TabControl>
我一直在玩这个。选择后,组合框数据绑定的源会发生一些变化。或者别的什么 我添加了诊断名称空间:
xmlns:debug="clr-namespace:System.Diagnostics;assembly=WindowsBase"
我把你的手机换成了带有大号喇叭的文本框,这样我就能看到事情真的在改变:
<TabItem Header="TabItem1" x:Name="TabItem1">
<TextBlock Name="tb1" FontSize="24" Text="1" Width="100" Height="26" />
</TabItem>
在选择和更改TabItem后,它仍然会将CombobBox切换为不显示选定项。就好像在TabControl更改选择后,DataContext被切换到TabControl.TabItem.TextBlock
所以我没有一个确切的答案给你们,但我有一些结果给你们
Bea Stollnitz有一篇关于使用这种诊断技术的好文章 根据hughdbrown的答案,我发现这将您的问题描述为一个bug。您可以使用这个XAML复制它(它与您的XAML有相反的问题):
福巴
嘶嘶作响
正如您所看到的,长度绑定工作正常,除了在下拉列表中,在下拉列表中,它将离开TabItem而不是内部的字符串
我不确定它是否适合您的目的,但您可以通过稍微不那么优雅并在ComboBoxItems中复制标题来绕过它:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TabControl Name="TabControl1" Width="220" Height="100" Canvas.Left="26" Canvas.Top="27">
<TabItem x:Name="TabItem1" Header="TabItem1">
<Grid/>
</TabItem>
<TabItem x:Name="TabItem2" Header="TabItem2">
<Grid/>
</TabItem>
</TabControl>
<ComboBox Name="CmbTabs" Width="120" Height="23" Canvas.Left="126" Canvas.Top="134"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}">
<ComboBoxItem>TabItem1</ComboBoxItem>
<ComboBoxItem>TabItem2</ComboBoxItem>
</ComboBox>
</Canvas>
表1
表2
我之所以开始考虑这个问题,是因为组合框出现了一些问题。不幸的是,我还没有解决我的问题,但我可以提供一些额外的见解和解决这个问题的方法。首先,让我们从对原始xaml的更改开始
<TabControl Height="100" Name="TabControl1" Width="220">
<TabItem Header="TabItem1" x:Name="TabItem1">
<TextBlock Text="TabItem1 Content" />
</TabItem>
<TabItem Header="TabItem2" x:Name="TabItem2">
<TextBlock Text="TabItem2 Content" />
</TabItem>
</TabControl>
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
DisplayMemberPath="Name"
>
</ComboBox>
请注意,我们可以在选项卡和组合控件的SelectedIndex之间创建双向绑定(本例中为默认绑定),而不是创建从选项卡控件到组合框的绑定,反之亦然。接下来,让我们向TabItems添加一些内容。此时,与Steve的建议类似,我们已经解决了“控制”问题。也就是说,更改选定的TabItem会更改选定的ComboBox项(您必须在这一点上信任我或继续阅读!),更改ComboBox会更改选定的TabItem。太好了
上述xaml还将DiplayMemberPath属性更改为“Name”。我想你会发现这消除了hughdbrown的“奇怪结果”。回想一下,Header属性(对象)是由ContentPresenter包装的。我认为,如果没有提供模板,默认行为是在TextBlock中将Header对象显示为字符串。因此,“奇怪的结果”正确地报告TextBlock控件不包含头属性
现在,让我们对前面的组合框xaml进行一些更改
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
这实际上产生了一个有趣的结果,并利用了我们添加到每个TabItem中的内容。当此代码运行时,您会注意到组合框现在显示所选选项卡项的内容。此外,列表现在为每个选项卡项显示“System.Windows.Controls.TabItem…”。我们可以将TextBlock绑定更改为{binding Header}并显示Header对象,但组合框仍然显示所选TabItem的内容。由于周五晚上已经很晚了,而且世界上没有足够的啤酒,所以我没有探究可能的原因。然而,我确实有一个解决办法
首先,让我们创建一个ValueConverter,将TabControl的Items集合转换为我们可以使用的内容。这是密码
public class TabItemCollectionConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ItemCollection collection = value as ItemCollection;
IList<string> names = new List<string>();
foreach (TabItem ti in collection.SourceCollection)
{
names.Add(ti.Header.ToString());
}
return names;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
公共类选项卡ItemCollectionConverter:IValueConverter
{
#区域转换器成员
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
ItemCollection collection=作为ItemCollection的值;
IList names=新列表();
foreach(collection.SourceCollection中的TabItem ti)
{
name.Add(ti.Header.ToString());
}
返回姓名;
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
抛出新的NotSupportedException();
}
#端区
}
转换器只是从TabControl的Items集合创建一个新集合,该集合包含来自每个TabItem的字符串化标题对象。这适用于简单的头对象,但显然有局限性。现在让我们考虑如何在XAML中使用这个。< /P>
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items, Converter={StaticResource ItemConverter}}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
请记住,ItemsSource绑定中使用的ValueConverter返回一个新集合。在本例中,我们将转换TabControl的Items集合
public class TabItemCollectionConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ItemCollection collection = value as ItemCollection;
IList<string> names = new List<string>();
foreach (TabItem ti in collection.SourceCollection)
{
names.Add(ti.Header.ToString());
}
return names;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items, Converter={StaticResource ItemConverter}}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<local:TabItemCollectionConverter x:Key="ItemConverter"/>