在WPF Tabcontrol标头模板中显示SelectedIndex [英] Show SelectedIndex in WPF Tabcontrol header template

查看:42
本文介绍了在WPF Tabcontrol标头模板中显示SelectedIndex的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我具有1 ... n个tabcontrol,并具有以下XAML设置:

 < TabControl名称="ordersTabControl" ItemsSource ="{Binding CoilItems}">< TabControl.ItemTemplate>< DataTemplate DataType ="models:Coil">< StackPanel>< TextBlock Text ="{Binding CoilCode,StringFormat ='Coil:{0}'}"/>< TextBlock Text ="{Binding ArticleCode,StringFormat ='Auftrag:{0}'}"/>< TextBlock Text ="{Binding RestWeight,StringFormat ='Restgewicht:{0} kg'}""/></StackPanel></DataTemplate></TabControl.ItemTemplate>< TabControl.ContentTemplate>[...]</TabControl.ContentTemplate></TabControl> 

打开的选项卡数量在运行时发生变化.现在,除了每个标题中已有的信息外,我想在每个标签中显示一个索引(即第一个标签显示订单1",第二个标签订单2",依此类推).

使用DataTemplate时的AFAIK我无法通过后面的代码访问tab-properties,那么XAML中有什么方法可以在tabheader内绑定文本块以在tabcontrol中显示该特定选项卡的索引?

我认为RelativeSource和FindAncestors应该有可能吗?las,我真的找不到关于这些设置的清晰教程(而且我只是两天前才开始使用WPF).

解决方案

我将使用附加属性为您提供解决方案.检查代码:

附加属性

 公共静态类IndexAttachedProperty{#region TabItemIndex公共静态int GetTabItemIndex(DependencyObject obj){返回(int)obj.GetValue(TabItemIndexProperty);}公共静态无效SetTabItemIndex(DependencyObject obj,int value){obj.SetValue(TabItemIndexProperty,value);}//使用DependencyProperty作为TabItemIndex的后备存储.这样可以启用动画,样式,绑定等.公共静态只读DependencyProperty TabItemIndexProperty =DependencyProperty.RegisterAttached("TabItemIndex",typeof(int),typeof(IndexAttachedProperty),新的PropertyMetadata(-1));#endregion#region TrackTabItemIndex公共静态布尔GetTrackTabItemIndex(DependencyObject obj){返回(布尔)obj.GetValue(TrackTabItemIndexProperty);}公共静态无效SetTrackTabItemIndex(DependencyObject obj,布尔值){obj.SetValue(TrackTabItemIndexProperty,value);}//使用DependencyProperty作为TrackTabItemIndex的后备存储.这样可以启用动画,样式,绑定等.公共静态只读DependencyProperty TrackTabItemIndexProperty =DependencyProperty.RegisterAttached("TrackTabItemIndex",typeof(布尔),typeof(IndexAttachedProperty),新的PropertyMetadata(false,TrackTabItemIndexOnPropertyChanged));私有静态无效TrackTabItemIndexOnPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e){var tabControl = GetParent(d,p => p是TabControl)作为TabControl;var tabItem = GetParent(d,p => p是TabItem)作为TabItem;如果(tabControl == null || tabItem == null)返回;如果(!(bool)e.NewValue)返回;int index = tabControl.Items.IndexOf(tabItem.DataContext == null?tabItem:tabItem.DataContext);SetTabItemIndex(d,index);}#endregion公共静态DependencyObject GetParent(DependencyObject项目,Func< DependencyObject,bool>条件){如果(item == null)返回null;返回条件(项目)?item:GetParent(VisualTreeHelper.GetParent(item),条件);}} 

此代码定义了两个附加属性,第一个属性用于设置项目是否跟踪其中包含的选项卡项目索引.第二个是index属性.

XAML示例代码:

 < TabControl.ItemTemplate>< DataTemplate DataType ="{x:Type WpfApplication3:A}">< StackPanel x:Name ="tabItemRoot" WpfApplication3:IndexAttachedProperty.TrackTabItemIndex ="True">< TextBlock Text ="{Binding Text}"/>< TextBlock Text ="{绑定路径=(WpfApplication3:IndexAttachedProperty.TabItemIndex),ElementName = tabItemRoot}"/></StackPanel></DataTemplate></TabControl.ItemTemplate> 

上面的代码是使用附加属性的示例.您可以轻松地适应您的代码.

结果:

希望这段代码对您有用...

I have 1...n tabcontrols in my application, with the following XAML setup:

<TabControl Name="ordersTabControl" ItemsSource="{Binding CoilItems}">
  <TabControl.ItemTemplate>
    <DataTemplate DataType="models:Coil">
      <StackPanel>
        <TextBlock Text="{Binding CoilCode, StringFormat='Coil: {0}'}" />
        <TextBlock Text="{Binding ArticleCode, StringFormat='Auftrag: {0}'}" />
        <TextBlock Text="{Binding RestWeight, StringFormat='Restgewicht: {0} kg'}" />
      </StackPanel>
    </DataTemplate>
  </TabControl.ItemTemplate>
  <TabControl.ContentTemplate>
  [...]
  </TabControl.ContentTemplate>
</TabControl>

The amount of open tabs changes at runtime. Now I'd like to show an index in each tab (i.e. the first tab shows "Order 1", the second "Order 2" and so on) in addition to the information already in each header.

AFAIK when using DataTemplate I can't access the tab-properties through the code-behind, so is there any way in XAML to bind a textblock inside a tabheader to show the Index of that specific tab in the tabcontrol?

I think it should be possible with RelativeSource and FindAncestors? Alas I couldn't really find any clear tutorial on those settings (and I only started using WPF 2 days ago).

解决方案

I'm going to give you a solution using attached properties. Check the code:

Attached Properties

public static class IndexAttachedProperty
{


    #region TabItemIndex

    public static int GetTabItemIndex(DependencyObject obj)
    {
        return (int) obj.GetValue(TabItemIndexProperty);
    }

    public static void SetTabItemIndex(DependencyObject obj, int value)
    {
        obj.SetValue(TabItemIndexProperty, value);
    }

    // Using a DependencyProperty as the backing store for TabItemIndex.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TabItemIndexProperty =
        DependencyProperty.RegisterAttached("TabItemIndex", typeof (int), typeof (IndexAttachedProperty),
                                            new PropertyMetadata(-1));



    #endregion

    #region TrackTabItemIndex

    public static bool GetTrackTabItemIndex(DependencyObject obj)
    {
        return (bool) obj.GetValue(TrackTabItemIndexProperty);
    }

    public static void SetTrackTabItemIndex(DependencyObject obj, bool value)
    {
        obj.SetValue(TrackTabItemIndexProperty, value);
    }

    // Using a DependencyProperty as the backing store for TrackTabItemIndex.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TrackTabItemIndexProperty =
        DependencyProperty.RegisterAttached("TrackTabItemIndex", typeof (bool), typeof (IndexAttachedProperty),
                                            new PropertyMetadata(false, TrackTabItemIndexOnPropertyChanged));

    private static void TrackTabItemIndexOnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var tabControl = GetParent(d, p => p is TabControl) as TabControl;
        var tabItem = GetParent(d, p => p is TabItem) as TabItem;
        if (tabControl == null || tabItem == null)
            return;
        if (!(bool)e.NewValue)
            return;
        int index = tabControl.Items.IndexOf(tabItem.DataContext == null ? tabItem : tabItem.DataContext);
        SetTabItemIndex(d, index);
    }
    #endregion





    public static DependencyObject GetParent(DependencyObject item, Func<DependencyObject, bool> condition)
    {
        if (item == null)
            return null;
        return condition(item) ? item : GetParent(VisualTreeHelper.GetParent(item), condition);
    }
}

This code define two attached properties, the first one is to set if an item tracks the the tab item index in wich it is contained. The second one is the index property.

XAML Sample code:

        <TabControl.ItemTemplate>
            <DataTemplate DataType="{x:Type WpfApplication3:A}">
                <StackPanel x:Name="tabItemRoot" WpfApplication3:IndexAttachedProperty.TrackTabItemIndex ="True">
                    <TextBlock Text="{Binding Text}"/>
                    <TextBlock Text="{Binding Path=(WpfApplication3:IndexAttachedProperty.TabItemIndex), ElementName=tabItemRoot}"/>

                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>

The above code is an example of using the attached property. You may adapt to your code easy.

Result:

Hope this code works for you...

这篇关于在WPF Tabcontrol标头模板中显示SelectedIndex的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆