Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use SelectedValueBinding with items defined in XAML #11220

Closed
TomEdwardsEnscape opened this issue May 3, 2023 · 1 comment · Fixed by #12193
Closed

Cannot use SelectedValueBinding with items defined in XAML #11220

TomEdwardsEnscape opened this issue May 3, 2023 · 1 comment · Fixed by #12193
Assignees
Labels

Comments

@TomEdwardsEnscape
Copy link
Contributor

Describe the bug
The SelectedValue system does not function when a TabControl contains items defined in XAML, through either Items or ItemsSource.

It's common in our WPF codebase to have multiple tab pages and display the one tagged with the value provided by an enum property on the viewmodel. This bug prevents us from replicating that design in Avalonia.

To Reproduce
Open samples\ControlCatalog\Pages\TabControlPage.xaml and change the first TabControl (currently line 25) so that it has these property values:

<TabControl SelectedValue="Leaf" SelectedValueBinding="{Binding Header}"

This will not compile due to an error in the compiled binding system:

Unable to resolve property or method of name 'Header' on type 'ControlCatalog.ViewModels.TabControlPageViewModel'.

Switch to ReflectionBinding and you will be able to build, but this exception will be thrown on startup:

System.ArgumentNullException
  HResult=0x80004003
  Message=Value cannot be null. (Parameter 'dataContext')
  Source=Avalonia.Controls
  StackTrace:
   at Avalonia.Controls.Primitives.SelectingItemsControl.BindingHelper.Evaluate(Object dataContext)
   at Avalonia.Controls.Primitives.SelectingItemsControl.OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
   ...

Expected behavior
The TabControl starts with the second TabItem (header "Leaf") selected. If SelectedValue changes, so does the active tab.

@grokys
Copy link
Member

grokys commented Jul 14, 2023

There are 2 parts to this I think:

  1. Compiled bindings are unable to determine the data type. This is because compiled bindings get their data type from the binding of ItemsSource, but Items is untyped and can contain any data type. This can be fixed by adding x:DataType, i.e.:
<TabControl SelectedValue="Leaf" SelectedValueBinding="{Binding Header}" x:DataType="TabItem">
  1. SelectedItemsControl.BindingHelper.Evaluate doesn't accept a null data context. I think this is a mistake. If one removes this restriction, then everything works as expected. Will open a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants