AvaloniaUI / avalonia-docs

https://docs.avaloniaui.net/docs/welcome
60 stars 190 forks source link

TabControl.ContentTemplate uses wrong DataContext #2 #445

Closed SimonORorke closed 5 months ago

SimonORorke commented 5 months ago

This is a follow on from closed Issue 13909 TabControl.ContentTemplate uses wrong DataContext, as I suggest it warrants further discussion. Let me reformulate the problem in a more long-winded way.

Following the instructions in the How To Bind Tabs page of Avalonia's documentation, in MainWindow.axaml I bound a TabControl to a collection property of MainWindowViewModel, like this:

<TabControl x:Name="TabControl"
            ItemsSource="{Binding Tabs}"
            SelectedItem="{Binding SelectedTab}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding ViewModel}" />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

The problem is apparent when looking at the same XAML in Rider: TabControl Binding Error TabControl.ItemTemplate, which defines the tab header, correctly binds to a property in the repeating item of the collection to which ItemsSource is bound. However, TabControl.ContentTemplate, which defines the content shown below the tab, incorrectly attempts to bind to a a non-existent property of the Window's view model instead of the required property of the repeating item.

The solution, as I found in Issue 13909, is to add a DataType to TabControl.ContentTemplate's DataTemplate, like this:

<TabControl.ContentTemplate>
    <DataTemplate DataType="viewModel:TabItemViewModel">
        <ContentControl Content="{Binding ViewModel}" />
    </DataTemplate>
</TabControl.ContentTemplate>

Is the difference between the binding behaviours of TabControl.ItemTemplate and TabControl.ContentTemplate a bug? Or is it as expected?

If it's not a bug, or perhaps till any bug has been fixed, the How To Bind Tabs documentation needs to be corrected.

timunie commented 5 months ago

It's by design when using compiled bindings as ItemTemplate can guess datatype if collections item type is known. ContentTemplate can't do that afaik as it could be any contentent if developers want to. So its a lack in the docs as these were written before we had CompiledBindings. A PR to fix docs is appreciated.

SimonORorke commented 5 months ago

Thanks for the explanation. What is a PR? Is it something you would like me to do to request the documentation fix?

timunie commented 5 months ago

PR = "Pull Request". Our docs are written in MarkDown and everyone can file a fix.

image

SimonORorke commented 5 months ago

OK, I'm happy to do it, but don't want to mess up, as it's my first time. Let's see if I've understood the procedure. I can see I could edit in place. But it is not obvious to me that that's what I should do. Do I need to create a branch with the edit for someone to approve?

timunie commented 5 months ago

No worries, you don't have write access anyways. So it should create a branch for you and a PR

SimonORorke commented 5 months ago

Got it. I’ll give it a go in a few hours, it’s 2:15am here in New Zealand.

SimonORorke commented 5 months ago

I have submitted the pull request.