我有一個自定義控制元件LoadingPanel,它有一個ActivityIndicator和一個Label. 我想在任何地方從控制元件外部訪問此活動指示器。只是我想改變它的 IsRunning 狀態。我可以使用它來做到這一點bool IsActivityIndicatorRunning,它運行良好,但我不想對每個屬性ActivityIndicator重復執行此操作,因此我想添加視圖并使用它的屬性。因此,我ActivityIndicator在自定義控制元件中,并希望將其映射到ActivityIndicator控制元件的 XAML 代碼中。
這是我的自定義控制元件 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;
}
uj5u.com熱心網友回復:
無需在XAML和C# Code Behind中宣告欄位(控制元件或視圖) 。在其中任何一個中宣告。無論您在何處宣告這些欄位,都應將它們設為公開,以便可以從您的自定義控制元件之外訪問它們。
請注意,默認情況下,在 XAML 中宣告的欄位、控制元件或視圖不是公共的。與 C# 類屬性相同,物件、欄位、控制元件默認為私有。
如果它們是公開的,您可以直接從外部使用自定義控制元件的子視圖。當您在 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(大寫)。
另請注意,您不會直接在控制元件上使用資料系結,而是在該控制元件的屬性上使用系結,例如標簽和Text屬性IsVisible、屬性等。因此從代碼中洗掉這些內容:ActivityIndicatorIsRunning
// 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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/456548.html
標籤:C# xml xamarin xamarin.forms 自定义控件
