簡體   English   中英

Xamarin Forms 自定義控件中如何添加View?

[英]How to add a View in Custom Control in Xamarin Forms?

我有一個自定義控件LoadingPanel ,它有一個ActivityIndicator cator 和一個Label 我想隨時隨地從控件外部訪問此活動指示器。 索性我想把它改成 IsRunning state。 我可以使用bool IsActivityIndicatorRunning來做到這一點,它運行良好,但我不想對ActivityIndicator cator 的每個屬性重復這樣做,因此我想添加視圖並使用它的屬性。 因此,我在自定義控件中有ActivityIndicator cator,並希望將它 map 到控件的 XAML 代碼中存在的ActivityIndicator cator。

這是我的自定義控件 LoadingPanel.xaml:

<StackLayout Orientation="Horizontal">
    <ActivityIndicator x:Name="activityIndicator" />
    <Label x:Name="loadingMessage" />
</StackLayout>

這是我的自定義控件背后的代碼:

public static readonly BindableProperty IsActivityIndicatorRunningProperty = BindableProperty.Create(nameof(IsActivityIndicatorRunning), typeof(bool), typeof(LoadingPanel), false, BindingMode.TwoWay, propertyChanged: IsActivityIndicatorRunningPropertyChanged);
public static readonly BindableProperty ActivityIndicatorProperty = BindableProperty.Create(nameof(ActivityIndicator), typeof(ActivityIndicator), typeof(LoadingPanel), propertyChanged: ActivityIndicatorPropertyChanged);

public bool IsActivityIndicatorRunning { get => (bool)GetValue(IsActivityIndicatorRunningProperty); set => SetValue(IsActivityIndicatorRunningProperty, value); }
public ActivityIndicator ActivityIndicator { get => (ActivityIndicator)GetValue(ActivityIndicatorProperty); set => SetValue(ActivityIndicatorProperty, value); }

public static void IsActivityIndicatorRunningPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
    var control = (LoadingPanel)bindable;
    control.activityIndicator.IsRunning = (bool)newValue;    // just remember this, continue ahead, till here working fine, just revise these concepts
}

public static void ActivityIndicatorPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
    var control = (LoadingPanel)bindable;
    control.activityIndicator = (ActivityIndicator)newValue;
}

這是我使用自定義控件的地方

<customControls:LoadingPanel x:Name="loadingPanel" />

我使用自定義控件的代碼隱藏

async void ChangeState(object sender, EventArgs e)
{
    loadingPanel.IsActivityIndicatorRunning = true; // This is working fine
    await Task.Delay(5000);

    // here I am getting NullReferenceException as it cannot find ActivityIndicator
    loadingPanel.ActivityIndicator.IsRunning = false;
}

無需在XAMLC# 代碼隱藏中聲明字段(控件或視圖)。 在其中任何一個中聲明。 無論您在哪里聲明字段,都將它們公開,以便可以從您的自定義控件外部訪問它們。

請注意,在 XAML 中聲明的字段、控件或視圖在默認情況下是不公開的。 同 C# Class 屬性、對象、字段、控件默認是私有的。

如果它們是公開的,您可以從外部直接使用自定義控件的子視圖。 正如您在 XAML 中所做的那樣,將其聲明為:

<StackLayout Orientation="Horizontal">
    <ActivityIndicator x:Name="ActivityIndicator" x:FieldModifier="public" />
    <Label x:Name="LoadingMessage" x:FieldModifier="public" />
</StackLayout>
// this should work now from outside of your custom control
loadingPanel.ActivityIndicator.IsRunning = false;

請注意,您有x:Name="activityIndicator" (小寫),但您嘗試使用loadingPanel.ActivityIndicator (大寫)。

另請注意,您不會直接在控件上使用數據綁定,而是在該控件的屬性上使用綁定,例如 Label 的TextIsVisible屬性、 ActivityIndicator cator 的IsRunning屬性等。因此,請從您的代碼中刪除這些內容:

// Remove this if you are already declaring ActivityIndicator in XAML
public ActivityIndicator ActivityIndicator { get => (ActivityIndicator)GetValue(ActivityIndicatorProperty); set => SetValue(ActivityIndicatorProperty, value); }

// Remove this as it is not required for Controls directly
public static readonly BindableProperty ActivityIndicatorProperty = BindableProperty.Create(nameof(ActivityIndicator), typeof(ActivityIndicator), typeof(LoadingPanel), propertyChanged: ActivityIndicatorPropertyChanged);

// Remove this
public static void ActivityIndicatorPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
    var control = (LoadingPanel)bindable;
    control.activityIndicator = (ActivityIndicator)newValue;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM