Mikkel Andersen
Mikkel Andersen

Reputation: 155

Xamarin: Using Community TabView to display two pages does not actually initialize the pages properly

I have the following code behind - it loads in two pages from the app container.

I then add these to the TabView item, using their content. However, since this approach does not begin any type of "initialization" I had to add the _overviewPageViewModel.OnAppearing();

However, the content of the pages does not update at all when the data changes. I therefore added a messaging center solution, which also does not do anything.

I know this is already a hacky solution - does anyone know how to display two pages in a TabView properly, or atleast how to reflect change updates?

public partial class AdminOverviewTab : StyledPage
{
    private ApprovalPage _approvalPage = App.AppContainer.Resolve<ApprovalPage>();
    private OverviewPage _overviewPage = App.AppContainer.Resolve<OverviewPage>();
    private OverviewPageViewModel _overviewPageViewModel = App.AppContainer.Resolve<OverviewPageViewModel>();

    public AdminOverviewTab()
    {
        InitializeComponent();
        _overviewPageViewModel.OnAppearing();
        var ApprovalPage = new TabViewItem()
        {
            Text = "Approval",
            FontSize = 12,
            Content = _approvalPage.Content
        };

        var OverviewPage = new TabViewItem()
        {
            Text = "Overview",
            FontSize = 12,
            Content = _overviewPage.Content
        };

        MessagingCenter.Subscribe<OverviewPageViewModel>(this, "realTimeBalanceUpdate", (sender) =>
        {
            _overviewPage = App.AppContainer.Resolve<OverviewPage>();

            OverviewPage = new TabViewItem()
            {
                Text = "Overview",
                FontSize = 12,
                Content = _overviewPage.Content
            };
            Tab.TabItems[1].Content = _overviewPage.Content;
        });
        Tab.TabItems.Clear();
        Tab.TabItems.Add(ApprovalPage);
        Tab.TabItems.Add(OverviewPage);
        IconImageSource = "overview";
        Title = "Overview";
    }
}

}

Upvotes: 0

Views: 579

Answers (1)

Wendy Zang - MSFT
Wendy Zang - MSFT

Reputation: 10958

You could use the INotifyPropertyChanged to update the data which you changed.

I make a tabview with two tabview items View1 and View2. In the View2 has a label with the Text BindableProperty. And there is a button in the tabview item View2. I use the button click event to update the data which i changed.

The code for TabView:

 public class Page8 : ContentPage, INotifyPropertyChanged
{
    private string _str;
    public string str
    {
        get { return _str; }
        set
        {
            _str = value;
            OnPropertyChanged("str");
        }
    }
    public Page8()
    {
        str = "hello";

        var view1 = new TabViewItem()
        {
            Text = "Approval",
            FontSize = 12,
            Content = new View1()

        };

        var v2 = new View2();
        v2.SetBinding(View2.TextProperty, "str");
        Button button = new Button();
        button.Clicked += delegate
        {
            str = "test";
        };

        var view2 = new TabViewItem()
        {
            Text = "Overview",
            FontSize = 12,
            Content = new StackLayout()
            {
                Children =
                {
                    v2,button
                }
            }
        };

        var tabView = new TabView();
        tabView.TabItems.Add(view1);
        tabView.TabItems.Add(view2);
        Title = "Overview";

        Content = tabView;

        this.BindingContext = this;

    }
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs((propertyName)));
    }

}

View2:

 Xaml:
   <ContentView.Content>
  <StackLayout>
      <Label x:Name="label" Text="{Binding Text}"  />
       
  </StackLayout>
 </ContentView.Content>



 Code behind:

  public partial class View2 : ContentView
{
    public static BindableProperty TextProperty = BindableProperty.Create(
propertyName: "Text",
returnType: typeof(string),
declaringType: typeof(View2),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.OneWay,
propertyChanged: OnPropertyChanged);


    public string Text
    {
        get
        {
            return (string)GetValue(TextProperty);
        }
        set
        {
            SetValue(TextProperty, value);
        }
    }
    private static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var contentview = bindable as View2;
        contentview.label.Text = newValue.ToString();

    }
    public View2()
    {
        InitializeComponent();
    }

 
}

Upvotes: 1

Related Questions