问题
I have a UWP MVVM application where I bind, amongst others, the following property to a DataGridComboBoxColumn
:
public List<ComboBoxValues> ListValues { get; set; } = new List<ComboBoxValues>();
XAML:
xmlns:local="using:MyProject.ViewModels"
<controls:DataGridComboBoxColumn Header="myHeader"
Binding="{Binding theSelectedValue, Mode=TwoWay}"
ItemsSource="{x:Bind local:PageVM.ListValues, Mode=OneWay}"
DisplayMemberPath="theValueOptions"/>
I use dependency injection, using Autofac to generate an instance of my viewModels when needed:
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<PageVM>().AsSelf();
I get the error: Static method 'ListValues' not found in type 'PageVM'.
I have tried googling it, and the only results that I find is that it should not be that easy to bind to a static property etc.
Why is x:bind expecting a static method? I don't want to use static properties/methods.
EDIT:
The DataContext
of pages are also set using a NavigationService and ViewModelBinder with code, though NOT the code-behind page. Autofac, the IoC manages the instances of those, the NavigationService and the ViewModelBinder. Thus, I do not know how to link the XAML to those instances to use x:Bind?
I do not want to use code behind, as I am trying to strictly stick to MVVM.
回答1:
Yeah so the problem is the below line:
ItemsSource="{x:Bind local:PageVM.ListValues, Mode=OneWay}"
What you're doing with this code is, telling the xaml BindingEngine
to look for a class called PageVM
under the xmlns:local
and then look for a field called ListValues
. Now since we don't have an instance of the PageVM
(as per the above line), it's considering ListValues
as static
and is trying to find it.
Generally to bind to a ViewModel
, you set the DataContext
of the Page
or UserControl
. You can do so like:
<Page.DataContext>
<local:PageVM x:Name="ViewModel"/>
</Page.DataContext>
if you're using a UserControl
the above would look like:
<UserControl.DataContext>
<local:PageVM x:Name="ViewModel"/>
</UserControl.DataContext>
and now use it in xaml
code like below:
<controls:DataGridComboBoxColumn Header="myHeader"
Binding="{Binding theSelectedValue, Mode=TwoWay}"
ItemsSource="{x:Bind ViewModel.ListValues, Mode=OneWay}"
DisplayMemberPath="theValueOptions"/>
Notice the x:Name="ViewModel"
, as part of the DataContext. This would allow you to reference your ViewModel
via the codebehind
too.
Edit After comments
Alternatively, if you cannot have a public parameterless constructor then I suggest you use the codebehind to create an instance of the ViewModel like below:
public PageVM ViewModel => this.DataContext as PageVM;
There is no clause that performs a null check on the above property since from the comments, the data context is being set via a dependency injection framework
and then use it the same way in your xaml code:
ItemsSource="{x:Bind ViewModel.ListValues, Mode=OneWay}"
来源:https://stackoverflow.com/questions/65719125/why-does-xbind-expect-a-static-method-to-bind-to