0
votes

I want to create a Tab Control which can hold for multiple User Controls.

<TabControl Padding="0">
    <TabItem Header="{x:Static p:Resources.Scheduler}" 
             Visibility="{Binding ShellService.IsSchedulerEnabled,
                                  Converter={StaticResource BoolToVisibilityConverter}}">
        <ContentControl>
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <Trigger Property="IsVisible" Value="True">
                            <Setter Property="Content" 
                                    Value="{Binding ShellService.LazySchedulerView.Value}"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </TabItem>
</TabControl>

The xaml is only for 1 tab item, which control by ShellService.IsSchedulerEnabled and the content is ShellService.LazySchedulerView.Value.

My problem here is that if I want to create a new TabItem, I have to create a new TabItem tag in the xaml.

How can I create a dynamic tab control to hold more than 1 tab item without specifying 'Value' in ContentControl.

public interface IShellService : INotifyPropertyChanged
{
    object ShellView { get; }

    bool IsSchedulerEnabled { get; set; }

    Lazy<object> LazySchedulerView { get; set; }
}

[Export(typeof(IShellService)), Export]
internal class ShellService : Model, IShellService
{
    private object _shellView;
    private bool _isSchedulerEnabled;
    private Lazy<object> _lazySchedulerView;

    public object ShellView
    {
        get { return _shellView; }
        set { SetProperty(ref _shellView, value); }
    }

    public bool IsSchedulerEnabled
    {
        get { return _isSchedulerEnabled; }
        set { SetProperty(ref _isSchedulerEnabled, value); }
    }

    public Lazy<object> LazySchedulerView
    {
        get { return _lazySchedulerView; }
        set { SetProperty(ref _lazySchedulerView, value); }
    }
}
1

1 Answers

1
votes

You can use Style for this TabItem. I created some example for you. You should change Bindings to your own. And you should create ObservableCollection of ShellServices and bind it to the TabControl. I hope this helps.

<TabControl ItemsSource="{Binding Objects}">
    <TabControl.Resources>
        <Style TargetType="TabItem" x:Key="{x:Type TabItem}">
            <Setter Property="Header" Value="{Binding Header}"></Setter>
            <Style.Triggers>
                <Trigger Property="IsVisible" Value="True">
                    <Setter Property="Content" Value="{Binding Text}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TabControl.Resources>
</TabControl>

Update

ViewModel Sample

public class OwnObject : ViewModelBase
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set { _text = value; NotifyPropertyChanged( "Text" ); }
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion
    protected void NotifyPropertyChanged( String info )
    {
        if ( PropertyChanged != null )
        {
            PropertyChanged( this, new PropertyChangedEventArgs( info ) );
        }
    }
}

I bound these objects to TabControl.

private ObservableCollection<OwnObject> _objects = new ObservableCollection<OwnObject>();
public ObservableCollection<OwnObject> Objects
{
    get { return _objects; }
    set { _objects = value; NotifyPropertyChanged( "Objects" ); }
}