如何在Xamarin中通过绑定隐藏导航工具栏按钮?
嘿,这个问题我之前踩过坑!Xamarin.Forms的ToolbarItem确实没自带可绑定的IsVisible属性,不过咱们可以通过两种简单的方式实现绑定控制它的显示隐藏,给你唠唠具体怎么做:
方案一:用附加属性实现(最简洁)
咱们可以写一个静态的附加属性类,通过监听属性变化来添加/移除ToolbarItem:
using Xamarin.Forms; namespace YourAppNameSpace // 换成你的项目命名空间 { public static class ToolbarItemExtensions { // 定义可绑定的IsVisible附加属性 public static readonly BindableProperty IsVisibleProperty = BindableProperty.CreateAttached( "IsVisible", typeof(bool), typeof(ToolbarItemExtensions), true, propertyChanged: OnIsVisibleChanged); // 获取属性值的方法 public static bool GetIsVisible(BindableObject bindable) { return (bool)bindable.GetValue(IsVisibleProperty); } // 设置属性值的方法 public static void SetIsVisible(BindableObject bindable, bool value) { bindable.SetValue(IsVisibleProperty, value); } // 属性变化时的逻辑:添加或移除ToolbarItem private static void OnIsVisibleChanged(BindableObject bindable, object oldValue, object newValue) { if (bindable is ToolbarItem item && item.Parent is ContentPage page) { var shouldBeVisible = (bool)newValue; if (shouldBeVisible && !page.ToolbarItems.Contains(item)) { page.ToolbarItems.Add(item); } else if (!shouldBeVisible && page.ToolbarItems.Contains(item)) { page.ToolbarItems.Remove(item); } } } } }
然后在你的XAML里引入命名空间,给ToolbarItem绑定这个附加属性:
<!-- 先在页面根节点添加命名空间引用 --> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppNameSpace" <!-- 替换成你的命名空间 --> x:Class="YourAppNameSpace.YourPage"> <!-- 你的页面内容 --> <ContentPage.ToolbarItems> <ToolbarItem Text="Save" Command="{Binding SaveCommand}" local:ToolbarItemExtensions.IsVisible="{Binding IsSaveButtonVisible}" /> </ContentPage.ToolbarItems> </ContentPage>
最后在你的ViewModel里添加IsSaveButtonVisible属性(记得实现INotifyPropertyChanged接口):
private bool _isSaveButtonVisible; public bool IsSaveButtonVisible { get => _isSaveButtonVisible; set { _isSaveButtonVisible = value; OnPropertyChanged(); // 触发属性变更通知 } }
方案二:用Behavior实现(更灵活)
如果你需要后续扩展更多ToolbarItem的逻辑,用Behavior会更合适:
using Xamarin.Forms; using System.ComponentModel; namespace YourAppNameSpace { public class ToolbarItemVisibilityBehavior : Behavior<ToolbarItem> { // 定义可绑定的IsVisible属性 public static readonly BindableProperty IsVisibleProperty = BindableProperty.Create(nameof(IsVisible), typeof(bool), typeof(ToolbarItemVisibilityBehavior), true); public bool IsVisible { get => (bool)GetValue(IsVisibleProperty); set => SetValue(IsVisibleProperty, value); } protected override void OnAttachedTo(ToolbarItem bindable) { base.OnAttachedTo(bindable); UpdateToolbarItemVisibility(bindable); bindable.BindingContextChanged += OnBindingContextChanged; } protected override void OnDetachingFrom(ToolbarItem bindable) { base.OnDetachingFrom(bindable); bindable.BindingContextChanged -= OnBindingContextChanged; } private void OnBindingContextChanged(object sender, EventArgs e) { UpdateToolbarItemVisibility(sender as ToolbarItem); } private void UpdateToolbarItemVisibility(ToolbarItem item) { if (item?.Parent is ContentPage page) { if (IsVisible && !page.ToolbarItems.Contains(item)) { page.ToolbarItems.Add(item); } else if (!IsVisible && page.ToolbarItems.Contains(item)) { page.ToolbarItems.Remove(item); } } } protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) { base.OnPropertyChanged(propertyName); if (propertyName == nameof(IsVisible)) { UpdateToolbarItemVisibility(AssociatedObject); } } } }
XAML里的用法:
<ContentPage.ToolbarItems> <ToolbarItem Text="Save" Command="{Binding SaveCommand}"> <ToolbarItem.Behaviors> <local:ToolbarItemVisibilityBehavior IsVisible="{Binding IsSaveButtonVisible}" /> </ToolbarItem.Behaviors> </ToolbarItem> </ContentPage.ToolbarItems>
ViewModel的写法和方案一一样就行~
两种方法都能完美实现你要的绑定控制,附加属性更轻量,Behavior扩展性更强,看你需求选就行!
内容的提问来源于stack exchange,提问作者Maulik shah
相关产品推荐
相关产品推荐

