【发布时间】: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