简体   繁体   中英

Model method binding not working in xaml

I am creating a UWP app using MVVM. In my xaml view, I have a ListView that is bound to an ObservableCollection, and Object_X is a model. Other properties of Object_X bound to my xaml view inside this list view are working properly. However, I have a button inside this List View, whose click event I want to be bound to a method I defined in my Object_X class, but when I compile my code, I am getting an "Object reference not set to an instance of an object error".

This is my xaml code. ObjectXCollection is a property in my view model. IsSelected and Value are properties of Object_X, and that binding is working perfectly. ExpandButtonHandler is also defined as a method in the Object_X class, but it is giving me the error. If I remove that click property, my code builds and runs fine. My model is implementing INotifyPropertyChanged, that's why the property binding are working properly. Can someone suggest a solution, or can someone see the problem?

    <ListView ItemsSource="{Binding ObjectXCollection, Mode=TwoWay}">
         <DataTemplate>
                <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" IsThreeState="True">
                    <TextBlock Text="{Binding Value}"/>
                </CheckBox>
                <Button Content=">>>" Click="{Binding ExpandButtonHandler}"></Button>
            </StackPanel>
        </DataTemplate>
    </ListView>

You can't bind to a Method, nor can you assign a Binding to an EventHandler. You can only set DependencyProperties to a Binding object by default.

Usually if I want to trigger some ViewModel code based on a UI event, I will use an AttachedCommandBehavior which allows you to use bindings in a UI event handler.

The end result looks something like this :

<Button x:Name="ExpandButton" Content=">>>"
        local:CommandBehavior.Event="Click"
        local:CommandBehavior.Action="{Binding ExpandButtonHandler}" />

The alternate solution is to just use code-behind the model, and call the method on your DataContext manually. Not as ideal, but it is an option.

private void ExpandButton_OnClick(object sender, EventArgs e)
{
    var vm = ExpandButton.DataContext as SomeViewModel;
    vm.ExpandButtonHandler();
}

Classic Binding doesn't allow direct binding to methods, but the new compiled binding, x:Bind does. You can read more about compiled data binding here .

<Button Click="{x:Bind ExpandButtonHandler}" Content=">>>" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM