Xaml 有没有办法强制执行OnSizeAllocated方法?

Xaml 有没有办法强制执行OnSizeAllocated方法?,xaml,xamarin,xamarin.forms,Xaml,Xamarin,Xamarin.forms,我已经使用Xaml代码创建了一个视图。我之所以使用代码隐藏,是因为我想根据设备方向更改视图的布局。因此,我面临的问题是,在加载视图后调用OnSizeAllocated方法。因此,无法根据设备方向更改布局。我只是想知道在加载视图之前是否有任何方法可以调用OnSizeAllocated方法。请点击以下链接查看代码: 由于尺寸位置没有改变,您不能强制运行,但您可以这样做以在初始加载时获得方向: 如果添加Xamarin.Essentials nuget包,可以使用这行代码DeviceDisplay.Ma

我已经使用Xaml代码创建了一个视图。我之所以使用代码隐藏,是因为我想根据设备方向更改视图的布局。因此,我面临的问题是,在加载视图后调用OnSizeAllocated方法。因此,无法根据设备方向更改布局。我只是想知道在加载视图之前是否有任何方法可以调用OnSizeAllocated方法。请点击以下链接查看代码:


由于尺寸位置没有改变,您不能强制运行,但您可以这样做以在初始加载时获得方向:

  • 如果添加Xamarin.Essentials nuget包,可以使用这行代码DeviceDisplay.MainDisplayInfo.orientation获取方向,您将获得横向、纵向、方形或未知
  • 如果不想添加包,可以使用Application.Current.MainPage.Width和Application.Current.MainPage.Height来确定方向

  • 1.重新排列页面

    您可以检查宽度是否大于高度,以确定设备现在是横向还是纵向:

    public partial class Page13 : ContentPage
    {
        private double _width ;
        private double _height ;
        private Grid grid;
        private Label label;
        private Entry entry;
        private Button button;
    
        public Page13 ()
        {
            _width = this.Width;
            _height = this.Height;
            label = new Label(){Text = "i am a laber"};
            entry = new Entry(){WidthRequest = 200};
            button = new Button(){Text = "Submit"};
            grid = new Grid();
            UpdateLayout();
            StackLayout stackLayout = new StackLayout();
            stackLayout.Children.Add(grid);
            Content = stackLayout;
    
        }
    
        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
            if (_width != width || _height != height)
            {
                _width = width;
                _height = height;
                UpdateLayout();
            }
        }
        void UpdateLayout()
        {
            grid.RowDefinitions.Clear();
            grid.ColumnDefinitions.Clear();
            grid.Children.Clear();
    
            if (_width > _height)
            {
                ScreenRotatedToLandscape();
            }
            else
            {
                ScreenRotatedToPortrait();
            }
        }
        private void ScreenRotatedToLandscape()
        {
            grid.RowDefinitions.Add(new RowDefinition(){Height = new GridLength(1,GridUnitType.Auto)});
            grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
            grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1,GridUnitType.Auto)});
            grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
            grid.Children.Add(label,0,0);
            grid.Children.Add(entry, 1, 0);
            grid.Children.Add(button, 0, 1);
            Grid.SetColumnSpan(button,2);
        }
    
        private void ScreenRotatedToPortrait()
        {
            grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
            grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
            grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
            grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
            grid.Children.Add(label, 0, 0);
            grid.Children.Add(entry, 0, 1);
            grid.Children.Add(button, 0, 2);
        }
    }
    
    这是从Xamarin.Forms文档中推荐的实现

    2.使用Xamarin.Essentials

    它为Xamarin中构建的跨平台应用程序添加了额外的功能。这些新功能之一是能够通过访问DeviceDisplay.ScreenMetrics.orientation属性为设备ping当前方向。这将返回当前设备方向,可用于确定要渲染的布局

    它和上面的一样

    private bool IsPortrait;
    
    public Page13 ()
    {
         ...
         IsPortrait = DeviceDisplay.ScreenMetrics.Orientation == ScreenOrientation.Portrait;
         UpdateLayout();
         ...
    
    }
    
    void UpdateLayout()
    {
        grid.RowDefinitions.Clear();
        grid.ColumnDefinitions.Clear();
        grid.Children.Clear();
    
        if (IsPortrait)
        {
            ScreenRotatedToPortrait();
        }
        else
        {
            ScreenRotatedToLandscape();
        }
    }
    

    为了将来的参考,请您将代码粘贴到这里,而不是添加代码的屏幕截图。为了调试和提供可能的解决方案,我可能需要运行您的代码,但我不会将其手动键入IDE。您可以在构造函数上设置网格子项。但是,您需要在size allocated事件上手动设置子级的rowdefinition和columndefinition,因为它总是在OnAppearing()之后调用。如果答案有用,您可以标记它吗!?非常感谢。