Search code examples
c#xamarin.formsxamarin-community-toolkit

Is it possible to open Expander from ViewModel?


I have an Expander in my View that every time I touch it it opens and displays data. Is it possible to open the Expander or close it from ViewModel? What I want to do is that the Expander can open or close it by pressing a Button.

MainPage.xaml:

    <StackLayout>
        <StackLayout>
            <CollectionView>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <ContentView>
                            <Frame>
                                <StackLayout>
                                    <Expander x:Name="expander"></Expander>
                                </StackLayout>
                            </Frame>
                        </ContentView>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
        <StackLayout>
            <ImageButton Source="img1" Command="{Binding xxxCommand}" CommandParameter="{Binding Source={x:Reference expander}, Path=.}"/>
        </StackLayout>
    </StackLayout>

ViewModel:

    xxxCommand = new Command((sender)=> {

     var exp = sender as Expander;
     exp.IsExpanded = !exp.IsExpanded;
     //...
            
});

When I open the app, I get this exception:

Xamarin.Forms.Xaml.XamlParseException: Can not find the object referenced by expander.


Solution

  • You could pass the Expander as parameter to the Command of the button .

    Set the name of Expander

     <Expander x:Name="exp">
    
     <Button Text="XXX"  Command="{Binding xxxCommand}" CommandParameter="{Binding Source={x:Reference exp}, Path=.}" />
    

    In ViewModel

    xxxCommand = new Command((sender)=> {
    
         var exp = sender as Expander;
         exp.IsExpanded = !exp.IsExpanded;
         //...
                
    });
    

    Update

    In your case you could use Data binding

    <StackLayout>
          <Expander  IsExpanded="{Binding IsExpanded}"></Expander>
    </StackLayout>
    
    <ImageButton Source="img1" Command="{Binding xxxCommand}"/>
    

    Add a new property in your model

    public class YourModel : INotifyPropertyChanged
    {
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void OnPropertyChanged(string propertyname)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
        }
    
        public bool isExpanded;
        public bool IsExpanded
        {
            get { return isExpanded; }
            set
            {
                isExpanded= value;
                OnPropertyChanged("IsExpanded");
            }
        }
    
    
        //...other properties
    
    }
    

    In ViewModel

    //list here is the ItemsSource of your listview
    ObservableCollection<YourModel> list = new ObservableCollection<YourModel>();
    
    //list.Add();
    //list.Add();
    //list.Add();
    //list.Add();
    
    Command xxxCommand = new Command(()=> {
    
       //if you want to open the first Expander  
    
       list[0].IsExpanded = true;
    
    
    });