0

How to add a RichTextBox to a Tab item so that can be added to a Tab Control and display corresponding content in the RichTextBox dynamically in MVVM format.

ViewModel

private ObservableCollection<TabItem> TabControl()
        {
            ObservableCollection<TabItem> Tabs= new ObservableCollection<TabItem>();

            return Tabs;
        }

Controller

  private void AddNewTabItem(string selectedItem)
    {
    try
        {

            System.Windows.Controls.RichTextBox richtextbox = new System.Windows.Controls.RichTextBox();
            richtextbox.Name = "richtextbox" + selectedItem;
            BrushConverter BC = new BrushConverter();
            richtextbox.Background = (SolidColorBrush)(BC.ConvertFrom("#FF098BBB"));
            richtextbox.Foreground = System.Windows.Media.Brushes.WhiteSmoke;
            richtextbox.IsReadOnly = true;

            TabItem m_tabItem = new TabItem();

            m_tabItem.Header = selectedItem;
            m_tabItem.Name = "tab" + selectedItem; 


            if (TabControl.Items.Count == 0)
            {
                TabControl.Items.Insert(0, m_tabItem);
                TabControl.SelectedIndex = msgTracerTabControl.Items.Count - 1;
            }
            else
            {
                TabControl.Items.Insert(msgTracerTabControl.Items.Count - 1, m_tabItem);
                TabControl.SelectedIndex = msgTracerTabControl.Items.Count - 2;
            }




            m_tabItem.Content = new System.Windows.Controls.RichTextBox();
            m_tabItem.Content = richtextbox;
            Tabs.add(m_tabItem);
        }
        catch (Exception EX)
        {

        }

    }

View

<TabControl  Grid.Column="1" Grid.Row="1" ItemsSource="{Binding TabControl}"  }"/>

I have used this code and working fine and this is not in MVVM this is WAF Architecture in that i'm using MVVM concept.

AJAY KUMAR
  • 77
  • 7
  • 1
    this is not MVVM compliant - there must be no TabItem or any gui related element in your viewmodel – GCamel Jun 12 '17 at 12:38
  • sorry it is not MVVM only MVVM concept iam using over there – AJAY KUMAR Jun 13 '17 at 06:17
  • MMV concept means nothing ! ==> you can't do that because contains which are gui element - and it is waiting for class associated to datatemplate - you mix everything.... – GCamel Jun 13 '17 at 08:00
  • Its working fine it is Architecture i.e WAF but the thing is richtextbox is not adding to the Tabitem which we had already done traditional WPF . – AJAY KUMAR Jun 13 '17 at 08:54
  • you can't do that because contains which are gui element – GCamel Jun 13 '17 at 08:59
  • it's not Gui Element it is present in the ViewModel and the function code is written in the Controller so is not GUI element and please look into the Question once again , Iam binding the i.e Collection of Tabitems to the Tabcontrol in the GUI – AJAY KUMAR Jun 13 '17 at 09:06
  • yes, that's what i said. TabItem is a gui element and they can't be in the ItemsSource collection ! ItemsSource="{Binding MyViewModelItem} must contains ViewModelItems associated to a datatemplate – GCamel Jun 13 '17 at 13:35
  • sry in WPF Application Framework it is be done by this way so Tabitem has to bind in this way what i have doing and i learnt from the architecture of the WAF – AJAY KUMAR Jun 14 '17 at 05:23

1 Answers1

2

You're not thinking MVVM. In a ViewModel you would not directly access UI elements but would rather set up bindings and data templates which would render your Viewmodels correctly. The correct approach is to have 2 viewmodels, 1 to act as a master and the second to act as the underlying DataContext for each tab.

A simple example would be something like this:

MainViewModel

    public class MainViewModel : BindableBase
    {
        private int _tabSuffix;
        public ObservableCollection<TextViewModel> TextTabs { get; set; } = new ObservableCollection<TextViewModel>();

    public DelegateCommand AddNewTabCommand { get; set; }

    public MainViewModel()
    {
        AddNewTabCommand = new DelegateCommand(OnAddNewTabCommand);
    }

    private void OnAddNewTabCommand()
    {
        TextTabs.Add(new TextViewModel()
        {
            Header = $"Tab #{_tabSuffix++}"
        });
    }
}

MainView

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Add new tab item" Command="{Binding AddNewTabCommand}"></Button>
        <TabControl Grid.Row="1"
                    ItemsSource="{Binding TextTabs}"
                    IsSynchronizedWithCurrentItem="True">
            <!-- Defines the header -->
            <TabControl.ItemTemplate>
                <DataTemplate DataType="{x:Type so44497239:TextViewModel}">
                    <TextBlock Text="{Binding Header}" />
                </DataTemplate>
            </TabControl.ItemTemplate>

            <!-- defines the context of each tab -->
            <TabControl.ContentTemplate>
                <DataTemplate DataType="{x:Type so44497239:TextViewModel}">
                    <RichTextBox Background="#FF098BBB" Foreground="WhiteSmoke" IsReadOnly="False" />
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>

TextViewModel

public class TextViewModel : BindableBase
    {
        public string Header { get; set; }
        public Brush BackgroundBrush { get; set; }
        public Brush ForegroundBrush { get; set; }

        public string Document { get; set; }
    }

In this example, the main viewmodel has no knowledge of the View but merely adds items to it's own ObservableCollection. The TabControl itself, through the binding to TextTabs, adds it's own tab items and renders them using the ItemTemplate and ContentTemplate properties.

Download code here

Barracoder
  • 3,696
  • 2
  • 28
  • 31
  • No I'm using MVVM concept but Actually it is Architecture WAF .so i want to add the Richtextboxes in each tab that are already binding to the Tabcontrol as i mentioned in the Question. so pls modify your answer @Mark Green – AJAY KUMAR Jun 13 '17 at 06:16
  • @Ajay, if you look into my answer, you'll see that each tab has a RichTextBox. It is included in the ContentTemplate of each TabItem. This is the correct way. – Barracoder Jun 13 '17 at 09:17