【问题标题】:Xamarin forms : Content View doesn't display in content pageXamarin 表单:内容视图不显示在内容页面中
【发布时间】:2018-05-29 05:41:45
【问题描述】:

我正在尝试在内容页面中加载内容视图。当我运行代码时,它不会点击我的内容视图。我正在从我的内容页面分配两个 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 类中的 ControllerNameIsBusy 应该是可绑定属性。 任何帮助为什么它没有点击这个视图。

【问题讨论】:

  • 您是否调试过您的视图?调用DesignScreenAsync 时是否设置了绑定?
  • @Johannes 它首先没有达到内容视图类。是的,我只是通过调试来尝试一切。
  • 断点被放入构造函数和/或DesignScreenAsync方法?没有人被击中?
  • @DiegoRafaelSouza 在这两个地方都设置了断点,但没有命中。

标签: xamarin xamarin.forms


【解决方案1】:

感谢大家抽出宝贵的时间。我实际上为自己找到了解决方案。

实际上出了问题的地方有两个。

  1. 只能在类初始化后设置可绑定属性。因此,如果我们在构造函数中调用DesignScreenAsync 方法,该方法采用ControllerName 的值显然会为null。解决方法是调用ControllerNamePropertyChanged方法中的方法。

代码如下:

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 设置默认值,因此为可绑定属性设置默认值很重要。

代码如下:

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

【讨论】:

    【解决方案2】:

    定义 async 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;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-02
      • 2016-10-03
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多