BindingContext not working after Xamarin update

TruffelNLTruffelNL USMember ✭✭

It's probably my fault but I can't figure out what the problem is. I have an app with a collapsable listview and I have a button in a row which can be clicked to decollapse the row. This worked great with the same code I have now, but now it gives me an error: Xamarin.Forms.Xaml.XamlParseException Position 77:37. Can not find the object referenced by 'PredictView'

The button is in a groupheader template, the binding to other items works.

In the PredictView.xaml file:
<ContentPage.BindingContext> <local:PredictViewModel /> </ContentPage.BindingContext>

Line 77(error line) of the same file:
<Button Image="{Binding StateIcon}" CommandParameter="{Binding .}" Command="{Binding BindingContext.ExpandCommand, Source={x:Reference Name=PredictView}}" HorizontalOptions="EndAndExpand" VerticalOptions="Center" Margin="0, 0, 12, 0" Style="{StaticResource buttonTransparent}"/>

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Source={x:Reference Name=PredictView}}"

    Do you have a control with that x:name on your view?

  • TruffelNLTruffelNL USMember ✭✭

    No, it's the x:Class name. I can remove that part, or let it refer to another control but then the button doesn't work.

  • LandLuLandLu Member, Xamarin Team Xamurai

    @TruffelNL Since your button is in a groupheader template, how do you set your listView's items source. It should also be a observable collection group and define your command there not in the item model. Try to show your code about local:PredictViewModel. Here is my collection:

    public class ListItemCollection : ObservableCollection<Item>
    {
        public ListItemCollection()
        {
            ExpandCommand = new Command<ListItemCollection>((listItem) =>
            {
    
            });
        }
    
        public Command<ListItemCollection> ExpandCommand { set; get; }
    }
    

    And the items source: var list = new ObservableCollection<ListItemCollection>();. I omitted the data added code and this command works fine on my side. Moreover try to make your button more clearly like:
    <Button Image="{Binding StateIcon}" CommandParameter="{Binding .}" Command="{Binding ExpandCommand}" HorizontalOptions="EndAndExpand" VerticalOptions="Center" Margin="0, 0, 12, 0" Style="{StaticResource buttonTransparent}"/>

  • TruffelNLTruffelNL USMember ✭✭

    @LandLu said:
    @TruffelNL Since your button is in a groupheader template, how do you set your listView's items source. It should also be a observable collection group and define your command there not in the item model. Try to show your code about local:PredictViewModel.

    The XAML(removed some code to make it readable):

    <ListView x:Name="predictList" ItemsSource="{Binding ExpandedWeeks}">

    The PredictViewModel(it's the ViewModel of Predict):

    public PredictViewModel()
    {
        Weeks = new NotifyTaskCompletion<ObservableCollection<WeekModel>>(WeekModel.GetWeeksFromDatabase() );
    
        ExpandCommand = new Command((key) =>
            {
                WeekModel item = (key as WeekModel);
                int selectedIndex = ExpandedWeeks.IndexOf(item);
                Weeks.Result[selectedIndex].Expanded = !Weeks.Result[selectedIndex].Expanded;
                ExpandWeeks();
                OnPropertyChanged("ExpandedWeeks");
            });
    }
    
    public void ExpandWeeks()
        {
            ExpandedWeeks = new ObservableCollection<WeekModel>();
    
            if (Weeks.Result != null && Weeks.Result.Count != 0)
            {
                foreach (WeekModel week in Weeks.Result)
                {
                    WeekModel tempWeek = new WeekModel();
                    tempWeek.CopyWeekModelFromThis(week);
    
                    if (tempWeek.Expanded)
                    {
                        foreach (MatchModel match in week)
                        {
                            match.MatchUpdateRunning = "false";
                            match.StatusIcon = "false";
                            tempWeek.Add(match);
                        }
                    }
                    ExpandedWeeks.Add(tempWeek);
                    if (tempWeek.FocusViewFromHere)
                    {
                        scrollToWeekModel = ExpandedWeeks[ExpandedWeeks.IndexOf(tempWeek)];
                    }
                }
            }
        }
    
    public NotifyTaskCompletion<ObservableCollection<WeekModel>> Weeks { get; set; }
    
    public ObservableCollection<WeekModel> ExpandedWeeks { get; set; }
    
    public ICommand ExpandCommand { get; set; }
    

    And the items source: var list = new ObservableCollection<ListItemCollection>();. I omitted the data added code and this command works fine on my side. Moreover try to make your button more clearly like:
    <Button Image="{Binding StateIcon}" CommandParameter="{Binding .}" Command="{Binding ExpandCommand}" HorizontalOptions="EndAndExpand" VerticalOptions="Center" Margin="0, 0, 12, 0" Style="{StaticResource buttonTransparent}"/>

    The reason I use the BindingContext.ExpandCommand etc. is because otherwise the button wouldn't work. I needed to use this as the ExpandCommand is in the ViewModel of Predict(called PredictViewModel, so it is not the Model of PredictView. A bit confusing I see now). The line the button is shown on is a WeekModel. The Model doesn't know how to collapse or decollapse the listview as the Predict-ViewModel(same as mentioned before) keeps track of a listview where it adds or removes matches from the list depending on whether the week is collapsed or decollapsed.

  • @TruffelNL - Did you find a solution to this? I am experiencing the same issue after updating to the latest Xamarin forms.

  • TruffelNLTruffelNL USMember ✭✭
    edited October 2018

    @BenSmith.1412 Oh man, there are a couple of options. I'm not quite sure which one solved it/I picked:

    • Downgraded again to an older Xamarin version(probably not, but not sure)
    • Make sure that the reference("Source={x:Reference Name=xxx}}") is the name of the xml. So the xxx need to be the same as the x:Name="xxx" in the <?xml> tags.
    • I had a "}" too much in the xaml code. So the code compiled and did run, but probably with unwanted effects.
    • The customer wanted the behaviour a bit different, so I removed the button and added an image and a stack layout with a tapgesturerecognizer. So the whole bar can be clicked, instead of the button.

    I hope one of these will help you out. I'd love to hear which one did the trick(I'm betting on number 2).

Sign In or Register to comment.