动态创建的TabItems w / MultiBinding和RelativeSource - > UnsetValue

时间:2014-06-25 09:37:51

标签: wpf xaml dynamic tabitem multibinding

在我的WPF应用程序中,我想在包含TabControl的可重用UserControl中动态创建TabItem。

TabControl的ItemsSource通过标准DataBinding绑定到ObservableCollection实例。

我创建了像这样的Tab项目 AFTER InitializeComponent()已被调用!

// ...
int itemCount = 0;
TabItem it = null;

it = new TabItem();
it.Header = "Sicherungen + Relais";
tabItemList.Insert(itemCount++, it);            

it = new TabItem();
it.Header = "Lage der Bauteile";
tabItemList.Insert(itemCount++, it);

it = new TabItem();
it.Header = "Schaltpläne";
tabItemList.Insert(itemCount++, it);

it = new TabItem();
it.Header = "Tipps + Tricks";
tabItemList.Insert(itemCount++, it);

好消息是,这些项目确实已添加到TabControl中,并带有各自的标题。

现在出现问题,当WPF试图在窗口变为可见之后向它们应用样式时!

我有TabItems的默认样式:

<Style TargetType="{x:Type TabItem}"
       BasedOn="{StaticResource TISTabItem}">
    <Setter Property="Width">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource convCategoryTabWidthConverter}">
                <Binding RelativeSource="{RelativeSource AncestorType={x:Type TabControl}, Mode=FindAncestor}" />
                <Binding RelativeSource="{RelativeSource AncestorType={x:Type TabControl}, Mode=FindAncestor}"
                         Path="ActualWidth" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Style>

转换器:

public class CategoryTabWidthConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values == null || values.Count() < 1)
            throw new ArgumentException("Values array passed is invalid.", "values");

        if(values[0] == DependencyProperty.UnsetValue)
        {
            return 0; // Added for breakpoint. Bailing out here!!!
        }

        TabControl tabCtrl = values[0] as TabControl;
        Double w = (tabCtrl.ActualWidth / tabCtrl.Items.Count);
        w = (w <= 1) ? 0.0 : (w - 1);
        return w;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

备注:我在其他两个地方使用此转换器和样式,其中TabItems在XAML中静态添加!在这些情况下,一切正常!

当动态添加TabItem时,TabControl RelativeSource及其ActualWidth都评估为DependencyProperty.UnsetValue

我预计会遇到一些逻辑错误。

何时应用样式?在TabItems正确添加到内部树之前还是之后? 有没有人对我在这里做错了什么有想法?

我会进一步调查,并提前感谢大家的帮助。

1 个答案:

答案 0 :(得分:0)

我自己解决了。问题是我忘记了ItemsSource的元素将被包装到TabItem实例中。

TabItem中的TabItem并不真正有意义。

直接将它们插入到TabControl.Items中会让它工作得令人惊讶。