【问题标题】:Dynamically created TabItems w/ MultiBinding and RelativeSource -> UnsetValue动态创建的 TabItems w/ MultiBinding 和 RelativeSource -> UnsetValue
【发布时间】:2014-08-15 19:25:19
【问题描述】:

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

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

我创建了这样的标签项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 中的!在这些情况下,一切正常!

但是,当动态添加 TabItems 时,TabControl RelativeSource 及其 ActualWidth 都计算为 DependencyProperty.UnsetValue

我预计我在这里遇到了一些逻辑错误。

什么时候应用样式?在 TabItems 正确添加到内部树之前还是之后? 有人知道我在这里做错了什么吗?

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

【问题讨论】:

    标签: wpf xaml dynamic tabitem multibinding


    【解决方案1】:

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

    TabItem 中的 TabItem 没有任何意义。

    直接将它们插入 TabControl.Items 效果惊人。

    【讨论】:

      猜你喜欢
      • 2011-03-09
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 2012-01-29
      • 1970-01-01
      相关资源
      最近更新 更多