why does x:Bind expect a static method to bind to?

混江龙づ霸主 提交于 2021-02-11 12:22:35

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!