Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用组合框控制TabControl活动选项卡_Wpf_Combobox_Tabcontrol - Fatal编程技术网

Wpf 使用组合框控制TabControl活动选项卡

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 />

我真正想要实现的是通过使用combobox作为导航控件来完全控制活动的TabItem

以下是我到目前为止得到的:

    <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"/>