0

我创建了一个具有水平条的自定义控件,根据我从 API 获得的数量,条中可以有 N 个 boxview,例如,我有一个限制为 20 个控件的控件,我选择了其中的 10 个,因此将有 10 个 boxview橙色,其余 10 来自 20 将是​​黑色我需要更新每个复选框选择的控件,它对我来说工作正常,直到我进入下一个屏幕并在我回到这个屏幕后回到同一个屏幕控制停止更新诡计调试我在我的代码中获取数据,但它没有在 UI 上更新。

我如何在我的代码中使用它

<views:CustomDashControl
        x:Name="customDash"
        Grid.Row="2"
        Grid.ColumnSpan="3"
        HorizontalOptions="FillAndExpand"
        ItemsSource="{Binding ControlData}"
        VerticalOptions="Start" />

我的自定义控件 XAML

<ContentView
    x:Class="LIRAppV1.Controls.CustomDashControl"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <StackLayout
        Padding="1"
        BackgroundColor="White"
        HorizontalOptions="CenterAndExpand"
        VerticalOptions="FillAndExpand">

        <!--<Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>-->

        <Grid
            x:Name="progressbar"
            BackgroundColor="Transparent"
            ColumnSpacing="0"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="Start">

            <Grid.RowDefinitions>
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>
        </Grid>
    </StackLayout>
</ContentView>

我的自定义控件的 CodeBehind

    public partial class CustomDashControl : ContentView
    {
        static int totalCount;
        static Color barColor;

        private static ObservableCollection<CustomControlData> tempData;

        public static ObservableCollection<CustomControlData> TempData
        {
            get { return tempData; }
            set
            {
                tempData = value;
                customDashControl.OnPropertyChanged("TempData");
            }
        }

        static CustomDashControl customDashControl;

        public CustomDashControl()
        {
            try
            {
                InitializeComponent();
                customDashControl = this;
            }
            catch (Exception ex)
            {
                BaseViewModel.HandleException(ex);
            }
        }

        #region Bindable Properties

        public static readonly BindableProperty ItemsSourceProperty =
            BindableProperty.Create("ItemsSource",
                                     typeof(ObservableCollection<CustomControlData>),
                                     typeof(CustomDashControl), new    
                                     ObservableCollection<CustomControlData>(),
                                     BindingMode.Default, null, OnItemsSourceChanged);

        private static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (oldValue != newValue)
            {
                (bindable as CustomDashControl).OnPropertyChanged("ItemsSource");

                TempData = (ObservableCollection<CustomControlData>)newValue;

                UpdateBar();
            }
        }

        private static void UpdateBar()
        {
            try
            {
                if (TempData != null && TempData.Count > 0)
                {
                    var control = customDashControl.progressbar;

                    control.ColumnDefinitions.Clear();
                    control.Children.Clear();

                    //Working
                    for (int i = 0, j = 0; i < TempData.Count; i++, j++)
                    {
                        control.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });

                        var tempBox = new BoxView() { Color = TempData[i].BarColor, WidthRequest = TempData[i].BarWidth };

                        control.Children.Add(tempBox, j, 0);

                        j++;

                        control.ColumnDefinitions.Add(new ColumnDefinition() { Width = 1 });

                        control.Children.Add(new BoxView() { Color = Color.White, WidthRequest = 1 }, (j), 0);
                    }

                    Console.WriteLine(control.Children);
                }
            }
            catch (Exception ex)
            {
                BaseViewModel.HandleException(ex);
            }
        }

        public ObservableCollection<CustomControlData> ItemsSource
        {
            get { return (ObservableCollection<CustomControlData>)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }


        public static readonly BindableProperty TotalCountProperty = BindableProperty.Create(propertyName: "TotalCount", returnType: typeof(int), declaringType: typeof(CustomDashControl), defaultValue: 0, propertyChanged: propertyChanges1);

        private static void propertyChanges1(BindableObject bindable, object oldValue, object newValue)
        {
            if (oldValue != newValue)
            {
                var control = bindable as CustomDashControl;
                totalCount = (int)newValue;

                if (totalCount > 0)
                {
                    (customDashControl.BindingContext as CustomDashControlViewModel).totalCount = totalCount;
                }
            }
        }

        public int TotalCount
        {
            get { return (int)GetValue(TotalCountProperty); }
            set { SetValue(TotalCountProperty, value); }
        }

        #endregion
    }
4

1 回答 1

0

OnAppearing 将在屏幕出现之前执行,当您想要一个需要在屏幕出现后立即执行的 Loaded 事件时,有一个解决方法。

在视图模型中创建一个属性,如下所示。

private bool _toggleTemp;
public bool ToggleTemp
{
    get => _toggleTemp;
    set => SetProperty(ref _toggleTemp, value);
}

将以下行添加到构造函数的最后一行。

LoadingVm.ToggleTemp = true;

在屏幕上添加一个 Switch 并将 IsVisible 设置为 false,如下所示。

<Switch IsToggled="{Binding ToggleTemp}" Toggled="Switch_OnToggled" IsVisible="False" />

现在您可以在 Switch_OnToggled 中的 Page Loaded 中编写您想要编写的代码。

private async void Switch_OnToggled(object sender, ToggledEventArgs e)
{ 
    /* Your code goes here... */ 
}

谢谢!

如果这不起作用,请参考 -

在 onappearing 中,我将所有内容都包装在一个异步调用中,并等待数百毫秒以使页面呈现。

await WaitAndExecute(1000, () =>
{
// refresh code
}

protected async Task WaitAndExecute(int milisec, Action actionToExecute)
{
await Task.Delay(milisec);
actionToExecute();
}

https://forums.xamarin.com/discussion/22561/page-loaded-event

于 2020-08-29T16:54:37.577 回答