[英]TabControl inside CustomControl loads with no selected tab item
我寫了一個支持直接內容的CustomControl。 當我在其中嵌套TabControl時,啟動時沒有選擇任何選項卡。 僅在使用ItemsSource時發生。 有人知道怎么了嗎?
實施范例
在MainWindow.xaml中:
<Window.DataContext>
<local:VM/>
</Window.DataContext>
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TabControl ItemsSource="{Binding Data}"/>
<local:CustomControl1 Grid.Column="1">
<TabControl ItemsSource="{Binding Data}" />
</local:CustomControl1>
</Grid>
VM.cs
class VM
{
public List<int> Data { get; set; } = new List<int>{ 1, 2, 3, 4 };
}
CustomControl1:
[ContentProperty("Content")]
public class CustomControl1 : Control
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public FrameworkElement Content
{
get { return (FrameworkElement)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(FrameworkElement), typeof(CustomControl1), new PropertyMetadata(null));
}
在Generic.xaml中:
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
經過一段時間的摸索,我找到了解決方案,但是我不確定此行為背后的確切原因。
我修改了您的示例,並比較了將TabControl
放在ContentControl
和CustomControl1
內時的行為。 可以預見,如果選擇ContentControl
則選擇第一個選項卡,但如果選擇CustomControl1
,則沒有選擇。 檢查ContentControl
源代碼 (特別是ContentControl.OnContentChanged
方法)后,我們可以看到它所做的是將其內容設置為其邏輯子級。
然后,我確認將TabControl
設置為CustomControl1
的邏輯子項是可以解決問題的(但我不確定為什么,如上所述)。 因此,解決問題的最小方法是處理控件及其內容在更改后的回調中的內容之間的邏輯關系,例如:
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register(
"Content",
typeof(FrameworkElement),
typeof(CustomControl1),
new PropertyMetadata(null)
{
PropertyChangedCallback = OnContentChanged
});
private static void OnContentChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var control = (CustomControl1)d;
if (e.OldValue != null)
control.RemoveLogicalChild(e.OldValue);
if (e.NewValue != null)
control.AddLogicalChild(e.NewValue);
}
請注意,盡管這缺少一些檢查(例如,新值是否已經具有邏輯父級,或者控件是否是模板的一部分),所以您可能只想從引用的源中復制代碼,或者回退到從中派生控件ContentControl
總共。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.