Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# StackLayout内部的Xamarin.Forms列表视图_C#_Xamarin_Xamarin.forms - Fatal编程技术网

C# StackLayout内部的Xamarin.Forms列表视图

C# StackLayout内部的Xamarin.Forms列表视图,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,在我的Xamarin项目中,我有一个相当简单的XAML表单,它应该显示两个视图,一个垂直的StackLayout,一个CameraView,一个ListView。CameraView将占用大部分空间。列表视图不得超过4-5项,但在运行期间会发生变化。以下是我目前掌握的XAML: <?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

在我的Xamarin项目中,我有一个相当简单的XAML表单,它应该显示两个视图,一个垂直的
StackLayout
,一个
CameraView
,一个
ListView
CameraView
将占用大部分空间。
列表视图
不得超过4-5项,但在运行期间会发生变化。以下是我目前掌握的XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         x:Class="Foo.CamPage"
         xmlns:ctrl="clr-namespace:Foo.Controls">
<ContentPage.Content>
    <StackLayout Orientation="Vertical">

        <ctrl:CameraView HeightRequest="2000"/>

        <StackLayout VerticalOptions="FillAndExpand">
            <ListView>
                  <ListView.ItemsSource>
                      <x:Array Type="{x:Type x:String}">
                        <x:String>Entry 1</x:String>
                        <x:String>Entry 2</x:String>
                      </x:Array>
                  </ListView.ItemsSource>
            </ListView>
        </StackLayout>

    </StackLayout>
</ContentPage.Content>
这是关联的iOS渲染器:

[assembly: ExportRenderer(typeof(CameraView), typeof(CamPreviewRenderer))]
namespace Foo.iOS.Renderers
{
    public class CamPreviewRenderer : ViewRenderer<CameraView, UICamPreview>
    {
        UICamPreview uiCameraPreview;

        protected override void OnElementChanged(ElementChangedEventArgs<CameraView> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                uiCameraPreview = new UICamPreview(e.NewElement.Camera);
                SetNativeControl(uiCameraPreview);
            }
            if (e.OldElement != null)
            {
                // Unsubscribe
                uiCameraPreview.Tapped -= OnCameraPreviewTapped;
            }
            if (e.NewElement != null)
            {
                // Subscribe
                uiCameraPreview.Tapped += OnCameraPreviewTapped;
            }
        }

        void OnCameraPreviewTapped(object sender, EventArgs e)
        {
            if (uiCameraPreview.IsPreviewing)
            {
                uiCameraPreview.CaptureSession.StopRunning();
                uiCameraPreview.IsPreviewing = false;
            }
            else
            {
                uiCameraPreview.CaptureSession.StartRunning();
                uiCameraPreview.IsPreviewing = true;
            }
        }
    }
}

任何提示都值得欣赏。

将这些视图放入两行网格中。一个视图希望使用与所需空间相同的空间,将“高度”设置为“自动”,另一个视图假设占用剩余空间,将“高度”设置为*。像这样的

<ContentPage.Content>
<StackLayout Orientation="Vertical">
 <Grid>
   <Grid.RowDefinitions>
   <RowDefinition Height="Auto"/>
   <RowDefinition Height="*" />
   </Grid.RowDefinitions>
    <ctrl:CameraView Grid.Row="0"/>

    <StackLayout VerticalOptions="FillAndExpand" Grid.Row="1">
        <ListView>
              <ListView.ItemsSource>
                  <x:Array Type="{x:Type x:String}">
                    <x:String>Entry 1</x:String>
                    <x:String>Entry 2</x:String>
                  </x:Array>
              </ListView.ItemsSource>
        </ListView>
    </Grid>
    </StackLayout>
   </StackLayout>
  </ContentPage.Content>

条目1
条目2

请记住,在布局方面,ListView是一个非常麻烦的工具。不管怎样,您可能不得不尝试设置高度的硬编码值。

您是否尝试过覆盖OnLayout,通常代码是这样的

protected override void only布局(bool changed,int l,int t,int r,int b)
{
尝试
{
仅基础布局(已更改,l、t、r、b);
如果(!已更改)
返回;
int msw=50;
int-msh=50;
int layoutWidth=r-l;
int-layouthweight=b-t;
msw=MeasureSpec.MakeMasureSpec(layoutWidth,MeasureSpecMode.Justice);
msh=MeasureSpec.MakeMeasureSpec(layouthweight,MeasureSpecMode.justice);
查看、测量(msw、msh);
视图.布局(0,0,layoutWidth,layoutHeight);
}
catch(System.Exception-ex)
{
Logger.WriteException(ex);
}

}
CameraView控件是否正确刷新视图?。当Xamarin绘制cameraview时,stacklayout的FillAndExpand会侵入所有视图。如果你只使用相机控制,看起来还可以吗?是的,CameraView本身工作得很好。对不起,伙计,网格方法看起来很有希望,但它不起作用。ListView占用了所有空间。外部堆栈布局是多余的,对吗?TableView会让事情变得更好吗?是的,请尝试删除它并将网格移动到实际的ListView中,看看这是否有帮助。FillAndExpand选项可能已导致占用整个空间。还可以尝试使用Fill和Expand选项将该摄影机视图包装到stacklayout中。父stacklayout是否有可能未展开?如果我在布局上遇到困难,我通常会给所有控件添加背景色,以查看边框的结束位置。试试看,看看每个控件的结束位置。这将更容易为您找出哪个视图没有扩展。哦,等等!那么你是说外部堆栈布局很重要?我删除了它,因为我认为这也是多余的。如果我将两个高度都设置为
*
,则两个视图共享相同的高度。这是一个开始。我发现你也可以说
5*
,这样一个视图就可以大五倍。然而,ListView从未消失,尽管我还没有消失!看起来很有希望,我现在就试试这个。这是查看的方法,对吗?
namespace Foo.iOS.Renderers
{
    public class UICamPreview : UIView
    {
        AVCaptureVideoPreviewLayer previewLayer;
        CameraOptions cameraOptions;

        public event EventHandler<EventArgs> Tapped;

        public AVCaptureSession CaptureSession { get; private set; }

        public bool IsPreviewing { get; set; }

        public UICamPreview(CameraOptions options)
        {
            cameraOptions = options;
            IsPreviewing = false;
            Initialize();
        }

        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
            previewLayer.Frame = rect;
        }

        public override void TouchesBegan(NSSet touches, UIEvent evt)
        {
            base.TouchesBegan(touches, evt);
            OnTapped();
        }

        protected virtual void OnTapped()
        {
            var eventHandler = Tapped;
            if (eventHandler != null)
            {
                eventHandler(this, new EventArgs());
            }
        }

        void Initialize()
        {
            CaptureSession = new AVCaptureSession();
            previewLayer = new AVCaptureVideoPreviewLayer(CaptureSession)
            {
                Frame = Bounds,
                VideoGravity = AVLayerVideoGravity.ResizeAspectFill
            };

            var videoDevices = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video);
            var cameraPosition = (cameraOptions == CameraOptions.Front) ? AVCaptureDevicePosition.Front : AVCaptureDevicePosition.Back;
            var device = videoDevices.FirstOrDefault(d => d.Position == cameraPosition);

            if (device == null)
            {
                return;
            }

            NSError error;
            var input = new AVCaptureDeviceInput(device, out error);
            CaptureSession.AddInput(input);
            Layer.AddSublayer(previewLayer);
            CaptureSession.StartRunning();
            IsPreviewing = true;
        }
    }
}
<ContentPage.Content>
<StackLayout Orientation="Vertical">
 <Grid>
   <Grid.RowDefinitions>
   <RowDefinition Height="Auto"/>
   <RowDefinition Height="*" />
   </Grid.RowDefinitions>
    <ctrl:CameraView Grid.Row="0"/>

    <StackLayout VerticalOptions="FillAndExpand" Grid.Row="1">
        <ListView>
              <ListView.ItemsSource>
                  <x:Array Type="{x:Type x:String}">
                    <x:String>Entry 1</x:String>
                    <x:String>Entry 2</x:String>
                  </x:Array>
              </ListView.ItemsSource>
        </ListView>
    </Grid>
    </StackLayout>
   </StackLayout>
  </ContentPage.Content>