简体   繁体   English

CustomControl中的TabControl加载时未选中任何选项卡

[英]TabControl inside CustomControl loads with no selected tab item

I wrote a CustomControl that supports direct content. 我写了一个支持直接内容的CustomControl。 When I nest a TabControl in it, there's no tab item selected on launch. 当我在其中嵌套TabControl时,启动时没有选择任何选项卡。 It happens only when using ItemsSource. 仅在使用ItemsSource时发生。 Anyone know what's wrong? 有人知道怎么了吗?

在此处输入图片说明

Sample implementation 实施范例

In MainWindow.xaml: 在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 VM.cs

class VM
{
    public List<int> Data { get; set; } = new List<int>{ 1, 2, 3, 4 };
}

CustomControl1: 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));
}

In Generic.xaml: 在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>

After some time of poking around I've found a solution, but I am not sure of the exact reasons behind this behavior. 经过一段时间的摸索,我找到了解决方案,但是我不确定此行为背后的确切原因。

I've modified your example and compared the behavior when the TabControl was put inside a ContentControl and a CustomControl1 . 我修改了您的示例,并比较了将TabControl放在ContentControlCustomControl1内时的行为。 Predictably, the first tab in case of ContentControl was selected, but in case of CustomControl1 it was not. 可以预见,如果选择ContentControl则选择第一个选项卡,但如果选择CustomControl1 ,则没有选择。 After inspecting the ContentControl source code (in particular the ContentControl.OnContentChanged method) we can see that what it does is it sets its content as its logical child. 检查ContentControl源代码 (特别是ContentControl.OnContentChanged方法)后,我们可以看到它所做的是将其内容设置为其逻辑子级。

I then confirmed that setting the TabControl as the CustomControl1 's logical child does the trick (but I'm not sure why, as I mentioned). 然后,我确认将TabControl设置为CustomControl1的逻辑子项是可以解决问题的(但我不确定为什么,如上所述)。 So the minimal solution to your problem is to handle the logical relation between your control and its content in the property changed callback, eg: 因此,解决问题的最小方法是处理控件及其内容在更改后的回调中的内容之间的逻辑关系,例如:

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);
}

Note though that this lacks some checks (eg if new value already does have a logical parent or the control is a part of a template), so you might want to simply copy the code from the referenced source, or fallback to deriving your control from ContentControl altogether. 请注意,尽管这缺少一些检查(例如,新值是否已经具有逻辑父级,或者控件是否是模板的一部分),所以您可能只想从引用的源中复制代码,或者回退到从中派生控件ContentControl总共。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM