I want to fill collection of ToolbarItems
from XAML
, but change visibility of some ToolbarItem
from view model.
I implemented BasePage
with some wrapper around ToolbarItems
collection:
public class BasePage : ContentPage
{
public IList<CustomToolbarItem> CustomToolbar { get; private set; }
public BasePage()
{
var items = new ObservableCollection<CustomToolbarItem>();
items.CollectionChanged += ToolbarItemsChanged;
CustomToolbar = items;
}
private void ToolbarItemsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ToolbarItems.Clear();
foreach (var item in CustomToolbar)
{
item.PropertyChanged += OnToolbarItemPropertyChanged;
if (item.IsVisible)
{
ToolbarItems.Add(item);
}
}
}
private void OnToolbarItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == CustomToolbarItem.IsVisibleProperty.PropertyName)
{
UpdateToolbar();
}
}
private void UpdateToolbar()
{
foreach (var item in CustomToolbar)
{
if (item.IsVisible)
{
ToolbarItems.Add(item);
}
else
{
ToolbarItems.Remove(item);
}
}
}
protected override void OnDisappearing()
{
base.OnDisappearing();
ToolbarItems.Clear();
CustomToolbar.Clear();
foreach (var item in CustomToolbar)
{
item.PropertyChanged -= OnToolbarItemPropertyChanged;
}
}
}
CustomToolbarItem.cs
:
public class CustomToolbarItem : ToolbarItem
{
public static readonly BindableProperty IsVisibleProperty =
BindableProperty.Create(nameof(IsVisible),
typeof(bool),
typeof(CustomToolbarItem),
true);
public bool IsVisible
{
get { return (bool)GetValue(IsVisibleProperty); }
set { SetValue(IsVisibleProperty, value); }
}
}
How I use it in XAML
:
<local:BasePage x:Name="Page"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ToolbarExtensionSample;assembly=ToolbarExtensionSample"
x:Class="ToolbarExtensionSample.SubPage">
<local:BasePage.CustomToolbar>
<local:CustomToolbarItem Name="Alloha"
IsVisible="{Binding IsItemVisible, Source={x:Reference Page}}"/>
</local:BasePage.CustomToolbar>
<Button Text="Click!"
Clicked="OnButtonClicked"/>
</local:BasePage>
My code is working, but I'm wondering is it okay for performance? Maybe, exists some better solution. Thanks in advance for suggestions to improvements or better approaches.