0
votes

Here is my scenario: I have a tab control whose ItemsSource is bound to a collection from another class. One of the controls in the DataTemplate is a custom TextEditor. I need to generate this in the backing code because I do a bit of customization.

Here is my XAML:

    <TabControl x:Name="tabControl">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Category}" />
            </DataTemplate>
        </TabControl.ItemTemplate>

        <TabControl.ContentTemplate>
            <DataTemplate>
                <text:TextEditor Buffer="{Binding Buffer}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

and here is what I would like to call instead for each TextEditor (rather than just setting the Buffer from the itemsSource as it does currently):

    public TextEditor CreateTextEditor(TextBuffer buffer, string category)
    {
        var editor = new TextEditor() { FontFamily = new FontFamily("Consolas"), FontSize = 12, IsReadOnly = true, AutoScroll = true };

        editor.SetBinding(TextEditor.ForegroundProperty, Theme.CreateBinding("ControlDisabledForegroundBrush"));

        if (this.loggingService == null)
        {
            editor.Buffer = TextBuffer.FromText("Unable to get logging service; logging output unavailable.");
        }
        else
        {
            editor.Buffer = buffer;
            editor.MoveCaret(editor.MapToCoordinate(editor.Buffer.TextData.End), false);
            var contextMenu = new ContextMenu();
            var item = new MenuItem { Header = "Clear All" };

            item.Click += (o, e) =>
            {
                using (var pencil = loggingService.Buffer.GetPencil())
                {
                    pencil.Write(new TextLocation(0, 0), loggingService.Buffer.TextData.End, TextData.Empty);
                }
            };
            contextMenu.Items.Add(item);
            editor.ContextMenu = contextMenu;
        }

        return editor;
    }

Is there a way that I can initialize the TextEditor with this code instead? I have access to the two parameters I need to pass into the method by using {Binding Buffer} and {Binding Category}.

1
Do you wish to use your CreateTextEditor method to configure the TextEditor for each TabItem? - Il Vic

1 Answers

1
votes

I ended up subclassing TabControl and overriding PrepareContainerForItemOverride()

    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        TabItem tabItem = (TabItem)element;
        LogBufferMapping bufferMapping = (LogBufferMapping)item;

        tabItem.Header = bufferMapping.Category;
        tabItem.Content = CreateTextEditor(bufferMapping.Buffer, bufferMapping.Category);
    }

Hope this helps if anyone is looking to do something similar.