Xamarin表单:内容视图不显示在内容页面中

时间:2018-05-29 05:41:45

标签: xamarin xamarin.forms

尝试在内容页面中加载内容视图。当我运行代码时,它没有点击我的内容视图。我从我的内容页面分配了两个Bindable参数。

内容页面

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:templates="clr-namespace:G2.Scanner.Views.Templates"           
         xmlns:viewModelBase="clr-namespace:G2.Scanner.ViewModels.Base;assembly=G2.Scanner"              
         xmlns:telerikPrimitives="clr-namespace:Telerik.XamarinForms.Primitives;assembly=Telerik.XamarinForms.Primitives"
         xmlns:local ="clr-namespace:G2.Scanner.Views.Transaction"
         x:Class="G2.Scanner.Views.Transaction.TransactionView"
         viewModelBase:ViewModelLocator.AutoWireViewModel="true">

        <local:GenerateScreen x:Name="generateScreen" ControllerName="{Binding ControllerName}" IsBusy="{Binding IsBusy}"/>

</ContentPage>

内容视图

public partial class GenerateScreen : ContentView
{
    #region BindableProperties
    public static readonly BindableProperty ControllerNameProperty = BindableProperty.Create("ControllerName", typeof(string), typeof(GenerateScreen));
    public static readonly BindableProperty IsBusyProperty = BindableProperty.Create("IsBusy", typeof(bool), typeof(GenerateScreen));
    #endregion

    #region Properties
    public string ControllerName
    {
        get { return (string)GetValue(ControllerNameProperty); }
        set { SetValue(ControllerNameProperty, value); }
    }

    public bool IsBusy
    {
        get { return (bool)GetValue(IsBusyProperty); }
        set { SetValue(IsBusyProperty, value); }
    }
    #endregion

    public GenerateScreen()
    {
        InitializeComponent();
        DesignScreenAsync();
    }

    public async void DesignScreenAsync()
    {
        IsBusy = true;

        // Some Design code..

        #region render
        scroll = new ScrollView
        {
            Content = layout
        };
        TransactionElements.Children.Add(scroll);
        #endregion
        IsBusy = false;
    }

Content View接受两个可绑定属性,并在加载时使用。

内容查看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"
             x:Class="G2.Scanner.Views.Transaction.GenerateScreen">
  <ContentView.Content>
        <StackLayout x:Name="TransactionElements"/>
    </ContentView.Content>
</ContentView>

我希望在加载内容页面时呈现此视图。 我发现,如果我在内容视图中不使用可绑定属性,则此方法有效。但根据我的要求,ContentView类中的 ControllerName IsBusy 应该是可绑定属性。 任何帮助,为什么它没有达到这个观点。

2 个答案:

答案 0 :(得分:0)

定义异步void方法大多数情况下都是不好的做法。 为了避免这种情况并且可能解决您的问题,您可以根据需要提供2种解决方案。

1)如果DesignScreen仅在没有密集调用的情况下构建UI,则必须同步执行:

  public GenerateScreen()
   {
    InitializeComponent();
    DesignScreenAsync();
   }

   public void DesignScreen()
   {
    IsBusy = true;

    // Some Design code..

    #region render
    scroll = new ScrollView
    {
        Content = layout
    };
    TransactionElements.Children.Add(scroll);
        #endregion
        IsBusy = false;
       }

2)如果你有需要等待的密集电话。使用Device.BeginInvokeOnMainThread执行密集调用并更新UI:

 public async void DesignScreenAsync()
 {
     IsBusy = true;

    await ApiIntensiveCall();
    // Some Design code..

    #region render
    Device.BeginInvokeOnMainThread(() =>
    {
      scroll = new ScrollView
      {
        Content = layout
      };
      TransactionElements.Children.Add(scroll);
      #endregion
    });

    IsBusy = false;

}

答案 1 :(得分:0)

谢谢所有人都抽出时间。我实际上为自己找到了解决方案。

实际上出了什么问题是在两个地方。

  1. 可绑定属性仅在类初始化后设置。因此,如果我们在构造函数中调用DesignScreenAsync方法,其值controller name将显然为null。解决方案是使用conrollerName ProprtyChanged方法调用该方法。
  2. 这是代码:

    public static readonly BindableProperty ControllerNameProperty = BindableProperty.Create(nameof(ControllerName), typeof(string), typeof(GenerateScreen),default(string), propertyChanged: OnControllerPropertyChange);
    
    private static void OnControllerPropertyChange(BindableObject bindable, object oldValue, object newValue)
    {
        ((GenerateScreen)bindable).DesignScreenAsync();
    }
    

    请注意,我已使用BindableObject来调用该方法。这是从相同的权限中调用该方法。

    1. contentView 未击中的原因是我没有为bool IsBusyProperty设置默认值,因此设置bindable的默认值很重要属性。
    2. 这是代码:

      public static readonly BindableProperty IsBusyProperty = BindableProperty.Create(nameof(IsBusy), typeof(bool), typeof(GenerateScreen),default(bool), defaultBindingMode: BindingMode.TwoWay);