我可以使用 BindableProperty 在我的 Xamarin ContentView 自定义控件中禁用按钮吗?

布兰索

我希望能够在我的 Xamarin.Forms 应用程序中禁用自定义标题 ContentView 中的按钮,以便我可以在导航离开包含它的 ContentPage 之前警告用户他们有未保存的数据。

我为 HeaderView 创建了一个 BindableProperty,我的包含页面绑定了它的视图模型。我受到这篇文章的启发:将具有绑定属性的自定义控件添加到您的 Xamarin.Forms 应用程序ContentView 的 XAML 在这里

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
             x:Class="HeaderView"
             x:Name="HeaderRoot">


       <Grid RowSpacing="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="80"/>
            <RowDefinition Height="5"/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0" Padding="20,20,20,0" ColumnSpacing="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="1.3*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

        <StackLayout Grid.Column="0">
                <FlexLayout HorizontalOptions="CenterAndExpand" VerticalOptions="Center">
                   <ImageButton x:Name="BackButton" TranslationY="-20" TranslationX="-20" BackgroundColor="Black"  HeightRequest="80" WidthRequest="80"  Source="angleleft.png" Padding="0,0,0,0" Margin="0,0,0,0" Clicked="OnBackClicked" IsEnabled="{Binding Source={x:Reference HeaderRoot}, Path=BindingContext.IsEnabled}" />
                </FlexLayout>
        </StackLayout>

        <FlexLayout Grid.Column="1" JustifyContent="Center" AlignItems="Center">
               <FlexLayout.TranslationY>
                <OnPlatform x:TypeArguments="x:Double">
                    <On Platform="Android" Value="-15"/>
                    <On Platform="iOS" Value="0"/>
                </OnPlatform>
            </FlexLayout.TranslationY>
           <Label x:Name="TitleLabel" FontFamily="{StaticResource TitleFont}" TextColor="White" FontSize="50" />
        </FlexLayout>

           </Grid>
    </Grid>
</ContentView>

ContentView 背后的相关代码在这里

    public partial class HeaderView : ContentView
    {
        public HeaderView()
        {
            InitializeComponent();

            if (DesignMode.IsDesignModeEnabled)
                return; // Avoid rendering exception in the editor.

            //Argument is null because the Header does not need navigation information.
            BindingContext = new HeaderViewModel(null);
        }
        public static BindableProperty CanNavigateProperty = 
                                 BindableProperty.Create(
            propertyName: "CanNavigate",
            returnType: typeof(bool),
            declaringType: typeof(HeaderView),
            defaultValue: true,
            defaultBindingMode: BindingMode.TwoWay,
            propertyChanged: HandleCanNavigatePropertyChanged);

        private static void HandleCanNavigatePropertyChanged(
            BindableObject bindable, 
            object oldValue, 
            object newValue)
        {
            HeaderView targetView = (HeaderView)bindable;

            if (targetView != null)
                targetView.BackButton.IsEnabled = (bool)newValue;
        }

//...

        public bool CanNavigate
        {
            get
            {
                return (bool)base.GetValue(CanNavigateProperty);
            }
            set
            {
                if(this.CanNavigate != value)
                {
                    base.SetValue(CanNavigateProperty, value);
                }
            }
        }


        protected void OnBackClicked(object sender, EventArgs e)
        {
            if (CanNavigate)
            {
                this.Navigation.PopAsync();
            }
        }

    }

编辑视图模型非常简单。

    public class HeaderViewModel : ViewModelBase
    {
        public HeaderViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            UserDTO dto = (Prism.PrismApplicationBase.Current as App).CurrentUser;
            UserName = string.Format("{0} {1}", dto.FirstName, dto.LastName);
        }

        private string userName;
        public string UserName 
        { 
            get
            {
                return userName; 
            }
            set
            {
                    SetProperty<string>(ref userName, value);
            }
        }
    }

然后我在包含页面中有以下标记

<mdaViews:HeaderView CanNavigate="{Binding IsSaved}" Title="COLLECTIONS" Grid.Row="0" />

我已验证属性 IsSaved 确实更改了其值。当在标签文本中使用时,绑定有效。

当我更改 IsSaved 属性的值时,标签将按预期从“true”更改为“false”。然而,这个相同的绑定似乎并没有改变我的自定义标头中的 CanNavigate 值。调试时,OnBackClicked 处理程序始终显示值 CanNavigate == true。永远不会输入 propertyChanged 事件 HandleCanNavigatePropertyChanged。如果我应该明确地调用它,我不知道如何。如果我遗漏了什么或使用了错误的方法,我想知道。

编辑SO 中的一些帖子似乎表明将 BindingContext 设置为视图模型可能是问题的一部分。

下面是这样一个示例:ContentView 中的 BindableProperty 不起作用我不确定我应该如何处理视图模型,因为它按预期工作。

布兰索

我在评论中找到了答案,“使用 ContentView 的页面设置了它的 BindingContext,然后它将用于所有子元素,包括自定义 ContentView。如果您再次在内容视图中设置上下文,您将覆盖它。” 由@Krumelur 撰写,他正在回复此答案https://stackoverflow.com/a/39989721/117995

当我在 ContentView 中设置 BindingContext 时,我覆盖了父页面中可用的所有内容。为了解决这个问题,我将所有 ViewModel 处理移到了后面的代码中,并删除了设置 BindingContext 的代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在我自己的 ContentView(自定义控件)中使用 Xamarin.Forms.Setter 类?

来自分类Dev

自定义控件中的 Xamarin BindableProperty

来自分类Dev

我可以将 Xamarin.Forms ContentPage 或 ContentView 嵌入 Wpf 窗口以快速使用 UI 吗?

来自分类Dev

Xamarin自定义BindableProperty与ObservableCollection

来自分类Dev

为什么我的 TemplateBinding 到我的自定义 TemplatedView 的 BindableProperty 不起作用

来自分类Dev

Xamarin.Forms:我可以将一个ContentPage或ContentView嵌入到另一个ContentPage中

来自分类Dev

我可以使用XAML在Xamarin.Forms中设计UI吗

来自分类Dev

我可以使用Xamarin在C#中开发Windows和Mac应用程序吗?

来自分类Dev

我可以使用Microsoft Band的SDK添加自定义按钮吗?

来自分类Dev

如何使我的自定义控件以Xamarin形式浮动?

来自分类Dev

我可以使用Netsuite的Bootstrap在Suitelet中创建自定义表单吗?

来自分类Dev

我可以使用外部程序在Google表格中运行自定义脚本吗?

来自分类Dev

我可以使用自定义工具替换Total Commander中的内部差异吗?

来自分类Dev

我可以使用自定义构造函数创建自定义数组吗?

来自分类Dev

从 Xamarin 中的 ContentView 返回 WebView

来自分类Dev

我可以使用python CSP吗?

来自分类Dev

我可以使用迭代器吗?

来自分类Dev

我可以使用通配符替换吗

来自分类Dev

我可以使用RTF格式吗?

来自分类Dev

骨骼可以使用我的插件吗?

来自分类Dev

我可以使用Plotly的自定义按钮来更新多面图中的`shared_yaxes`吗?

来自分类Dev

我可以创建一个使用Generic.xml中的另一个自定义控件的自定义控件吗

来自分类Dev

我可以使用新的@import指令导入自定义框架吗?

来自分类Dev

我可以使用自定义标志扩展git命令吗?

来自分类Dev

我可以使用Jquery将自定义属性插入HTML元素吗?

来自分类Dev

我可以使用此自定义功能替换内置的pow功能吗?

来自分类Dev

我可以使用Git将更新补丁应用于自定义软件吗?

来自分类Dev

我们可以编写自定义检查以使用Data Dog监视过程吗

来自分类Dev

我可以自定义Elixir iex以使用ctrl-D退出吗?

Related 相关文章

  1. 1

    如何在我自己的 ContentView(自定义控件)中使用 Xamarin.Forms.Setter 类?

  2. 2

    自定义控件中的 Xamarin BindableProperty

  3. 3

    我可以将 Xamarin.Forms ContentPage 或 ContentView 嵌入 Wpf 窗口以快速使用 UI 吗?

  4. 4

    Xamarin自定义BindableProperty与ObservableCollection

  5. 5

    为什么我的 TemplateBinding 到我的自定义 TemplatedView 的 BindableProperty 不起作用

  6. 6

    Xamarin.Forms:我可以将一个ContentPage或ContentView嵌入到另一个ContentPage中

  7. 7

    我可以使用XAML在Xamarin.Forms中设计UI吗

  8. 8

    我可以使用Xamarin在C#中开发Windows和Mac应用程序吗?

  9. 9

    我可以使用Microsoft Band的SDK添加自定义按钮吗?

  10. 10

    如何使我的自定义控件以Xamarin形式浮动?

  11. 11

    我可以使用Netsuite的Bootstrap在Suitelet中创建自定义表单吗?

  12. 12

    我可以使用外部程序在Google表格中运行自定义脚本吗?

  13. 13

    我可以使用自定义工具替换Total Commander中的内部差异吗?

  14. 14

    我可以使用自定义构造函数创建自定义数组吗?

  15. 15

    从 Xamarin 中的 ContentView 返回 WebView

  16. 16

    我可以使用python CSP吗?

  17. 17

    我可以使用迭代器吗?

  18. 18

    我可以使用通配符替换吗

  19. 19

    我可以使用RTF格式吗?

  20. 20

    骨骼可以使用我的插件吗?

  21. 21

    我可以使用Plotly的自定义按钮来更新多面图中的`shared_yaxes`吗?

  22. 22

    我可以创建一个使用Generic.xml中的另一个自定义控件的自定义控件吗

  23. 23

    我可以使用新的@import指令导入自定义框架吗?

  24. 24

    我可以使用自定义标志扩展git命令吗?

  25. 25

    我可以使用Jquery将自定义属性插入HTML元素吗?

  26. 26

    我可以使用此自定义功能替换内置的pow功能吗?

  27. 27

    我可以使用Git将更新补丁应用于自定义软件吗?

  28. 28

    我们可以编写自定义检查以使用Data Dog监视过程吗

  29. 29

    我可以自定义Elixir iex以使用ctrl-D退出吗?

热门标签

归档