Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.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# 如何使用Xamarin窗体在半帧中放置图像_C#_Listview_Xamarin_Xamarin.forms - Fatal编程技术网

C# 如何使用Xamarin窗体在半帧中放置图像

C# 如何使用Xamarin窗体在半帧中放置图像,c#,listview,xamarin,xamarin.forms,C#,Listview,Xamarin,Xamarin.forms,我想在我的应用程序中的半帧中放置一个图像,我正在使用xamarin表单来执行此操作,我如何执行此操作 我的Xaml <StackLayout HorizontalOptions = "FillAndExpand" VerticalOptions="StartAndExpand" > <ListView x:Name="lv_search" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExp

我想在我的应用程序中的半帧中放置一个图像,我正在使用xamarin表单来执行此操作,我如何执行此操作

我的Xaml

 <StackLayout HorizontalOptions = "FillAndExpand" VerticalOptions="StartAndExpand" >
        <ListView x:Name="lv_search" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" RowHeight="175" SeparatorColor="White">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <AbsoluteLayout HorizontalOptions = "FillAndExpand" VerticalOptions="StartAndExpand" >
                            <Frame BackgroundColor = "White" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand" Margin="20,10,0,0"
                             HeightRequest="75" AbsoluteLayout.LayoutBounds="0.01,0.9,1,1" AbsoluteLayout.LayoutFlags="All">
                                <Image Source = "img_frm" BackgroundColor="#14559a" AbsoluteLayout.LayoutBounds="0.009,0.9,0.3,0.6" AbsoluteLayout.LayoutFlags="All"  />
                                <StackLayout Orientation = "Horizontal"  HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
                                    <AbsoluteLayout HorizontalOptions = "StartAndExpand" >
                                        <Image Source="ellipse_1" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" AbsoluteLayout.LayoutFlags="All"
                                        AbsoluteLayout.LayoutBounds="0.01,0.4,1,1" HeightRequest="100" WidthRequest="100" BackgroundColor="White"/>
                                        <Image Source = "{Binding Image}" AbsoluteLayout.LayoutBounds="0.02,0.4,1,1" AbsoluteLayout.LayoutFlags="All"
                                           HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"  ></Image>
                                    </AbsoluteLayout>
                                    <Label x:Name="lbl_categories" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"  Margin="10,0,0,0" 
                                      TextColor="Black"   Text="{Binding Title}" LineBreakMode="WordWrap"  HorizontalTextAlignment="Start"
                                      FontSize="Medium" FontAttributes="Bold" AbsoluteLayout.LayoutBounds="0.3,0.3,1,1" AbsoluteLayout.LayoutFlags="All"/>
                                    <Image HorizontalOptions = "EndAndExpand" VerticalOptions="Center" Source="arrow"  AbsoluteLayout.LayoutBounds="0.9,0.3,0.3,0.3"
                                      AbsoluteLayout.LayoutFlags="All" />
                                </StackLayout>
                            </Frame>
                        </AbsoluteLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        </StackLayout>

但是我得到了这样的设计,如何将设计修改成上面的图像


您可以使用
网格
而不是
绝对布局

我没有对此进行测试,但请尝试以下方法:

<Grid 
    HorizontalOptions="FillAndExpand" 
    VerticalOptions="StartAndExpand">
    <Frame 
        Grid.Row="0"
        Grid.Column="0"
        BackgroundColor="White" 
        HorizontalOptions="FillAndExpand" 
        VerticalOptions="StartAndExpand" 
        Margin="20,10,0,0"
        HeightRequest="75">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Image 
                Grid.Row="0"
                Grid.Column="0"
                Source="ellipse_1" 
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="Start" 
                HeightRequest="100" 
                WidthRequest="100" 
                BackgroundColor="White">
            </Image>
            <Image 
                Grid.Row="0"
                Grid.Column="1"
                Source="{Binding Image}" 
                HorizontalOptions="CenterAndExpand" 
                VerticalOptions="CenterAndExpand">
            </Image>
            <Label 
                Grid.Row="0"
                Grid.Column="2"
                x:Name="lbl_categories" 
                HorizontalOptions="FillAndExpand" 
                VerticalOptions="CenterAndExpand" 
                Margin="10,0,0,0" 
                TextColor="Black"
                Text="{Binding Title}" 
                LineBreakMode="WordWrap"
                HorizontalTextAlignment="Start"
                FontSize="Medium" 
                FontAttributes="Bold">
            </Label>
            <Image 
                Grid.Row="0"
                Grid.Column="3" 
                HorizontalOptions="EndAndExpand" 
                VerticalOptions="Center" 
                Source="arrow">
            </Image>
        </Grid>
    </Frame>
    <Image 
        Margin="10,10,0,0"
        Grid.Row="0"
        Grid.Column="0"
        Source="img_frm" 
        BackgroundColor="#14559a">
    </Image>
</Grid>
public class RoundedBoxView : BoxView
{
    readonly BindableProperty CornerRadiusProperty = BindableProperty.Create("CornerRadius", typeof(double), typeof(double), 0.0);

    public double CornerRadius
    {
        get { return (double)GetValue(CornerRadiusProperty); }
        set { SetValue(CornerRadiusProperty, value); }
    }
}


由于
图像
是在xaml中的
之后创建的,因此它与
重叠。您可能需要根据需要更改
框架
和蓝色方形
图像
的边距。

您可以使用
网格
而不是
绝对布局

我没有对此进行测试,但请尝试以下方法:

<Grid 
    HorizontalOptions="FillAndExpand" 
    VerticalOptions="StartAndExpand">
    <Frame 
        Grid.Row="0"
        Grid.Column="0"
        BackgroundColor="White" 
        HorizontalOptions="FillAndExpand" 
        VerticalOptions="StartAndExpand" 
        Margin="20,10,0,0"
        HeightRequest="75">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Image 
                Grid.Row="0"
                Grid.Column="0"
                Source="ellipse_1" 
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="Start" 
                HeightRequest="100" 
                WidthRequest="100" 
                BackgroundColor="White">
            </Image>
            <Image 
                Grid.Row="0"
                Grid.Column="1"
                Source="{Binding Image}" 
                HorizontalOptions="CenterAndExpand" 
                VerticalOptions="CenterAndExpand">
            </Image>
            <Label 
                Grid.Row="0"
                Grid.Column="2"
                x:Name="lbl_categories" 
                HorizontalOptions="FillAndExpand" 
                VerticalOptions="CenterAndExpand" 
                Margin="10,0,0,0" 
                TextColor="Black"
                Text="{Binding Title}" 
                LineBreakMode="WordWrap"
                HorizontalTextAlignment="Start"
                FontSize="Medium" 
                FontAttributes="Bold">
            </Label>
            <Image 
                Grid.Row="0"
                Grid.Column="3" 
                HorizontalOptions="EndAndExpand" 
                VerticalOptions="Center" 
                Source="arrow">
            </Image>
        </Grid>
    </Frame>
    <Image 
        Margin="10,10,0,0"
        Grid.Row="0"
        Grid.Column="0"
        Source="img_frm" 
        BackgroundColor="#14559a">
    </Image>
</Grid>
public class RoundedBoxView : BoxView
{
    readonly BindableProperty CornerRadiusProperty = BindableProperty.Create("CornerRadius", typeof(double), typeof(double), 0.0);

    public double CornerRadius
    {
        get { return (double)GetValue(CornerRadiusProperty); }
        set { SetValue(CornerRadiusProperty, value); }
    }
}


由于
图像
是在xaml中的
之后创建的,因此它与
重叠。您可能需要根据需要更改
和蓝色方形
图像
的边距。

我不想这么说,但对于您想要实现的结果,您的xaml是一场噩梦。这不仅是因为视觉树中的元素过多,还因为在ListView中使用AbsoluteLayout

尽管这在技术上是可能的,但它会导致你的应用程序性能下降,尤其是当你的ListView中填充了大量项目时

其次,为那个蓝色方块创建一个图像也是一种内存浪费,如果你的ListView包含很多条目,会导致更多的性能下降,最终可能导致Android上的OutOfMemoryException

可以将其替换为从长方体视图继承的自定义视图,并使用自定义渲染器渲染圆角

还要避免在ListView中使用StackLayout,因为这也会导致性能问题,因为StackLayout在布局时会进行大量计算

正如Dennis已经提到的,您的方法是使用网格进行布局,记住,添加到网格中的所有元素将按照它们在xaml定义中添加的顺序相互覆盖

尤其是在使用ListView时,尽量少使用元素,避免使用需要大量布局过程的元素

尽管我在我的示例中没有使用它,但我想添加一个信息,即您也可以使用负边距值进行高级元素定位

下面是一个简单的例子,我一起黑客:

<ListView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" RowHeight="80">
        <ListView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <!-- quick hack to make the list view populate items without having to write model classes -->
                <x:String>Entry 1</x:String>
                <x:String>Entry 2</x:String>
                <x:String>Entry 3</x:String>
                <x:String>Entry 4</x:String>
            </x:Array>
        </ListView.ItemsSource>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
                        <BoxView BackgroundColor="LightGray" Margin="19,9,9,9" />
                        <Grid Margin="20,10,10,10" BackgroundColor="White">
                            <Label Text="{Binding .}" VerticalOptions="Center" FontSize="18" Margin="25,0,0,0"/>
                            <!-- insert icons, labels, etc here -->
                        </Grid>
                        <customs:RoundedBoxView BackgroundColor="DarkBlue" CornerRadius="6" WidthRequest="15" VerticalOptions="FillAndExpand" HorizontalOptions="Start" Margin="10,20,0,20" />
                </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
这将是android的自定义渲染器:

[assembly: ExportRenderer(typeof(RoundedBoxView), typeof(RoundedBoxViewRenderer))]
namespace TestApp.Droid
{
public class RoundedBoxViewRenderer : BoxRenderer
{
    public RoundedBoxViewRenderer(Context context) : base(context)
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
    {
        base.OnElementChanged(e);
        SetWillNotDraw(false);
        Invalidate();
    }

    public override void Draw(Canvas canvas)
    {
        var box = Element as RoundedBoxView;
        var rect = new Rect();
        var paint = new Paint()
        {
            Color = box.BackgroundColor.ToAndroid(),
            AntiAlias = true,
        };
        GetDrawingRect(rect);
        var radius = (float)(box.CornerRadius); 
        canvas.DrawRoundRect(new RectF(rect), radius, radius, paint);
    }
}
[程序集:ExportRenderer(typeof(RoundedBoxView)、typeof(RoundedBoxViewRenderer))]
名称空间TestApp.Droid
{
公共类RoundedBoxViewRenderer:BoxRenderer
{
public RoundedBoxViewRenderer(上下文):基本(上下文)
{
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
SetWillNotDraw(假);
使无效();
}
公共覆盖无效绘制(画布)
{
变量框=元素为RoundedBoxView;
var rect=new rect();
var paint=new paint()
{
Color=box.BackgroundColor.ToAndroid(),
反别名=真,
};
GetDrawingRect(rect);
变量半径=(浮动)(方格角半径);
canvas.DrawRoundRect(新的RectF(rect)、半径、半径、绘制);
}
}
对于iOS:

[assembly: ExportRenderer(typeof(RoundedBoxView), typeof(RoundedBoxViewRenderer))]
namespace TestApp.iOS
{
public class RoundedBoxViewRenderer: BoxRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
    {
        base.OnElementChanged(e);
        if (Element != null)
        {
            Layer.MasksToBounds = true;
            UpdateCornerRadius(e.NewElement as RoundedBoxView);
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == CircleView.WidthProperty.PropertyName || e.PropertyName == CircleView.HeightProperty.PropertyName)
        {
            UpdateCornerRadius(Element as RoundedBoxView);
        }
    }

    void UpdateCornerRadius(RoundedBoxView box)
    {
        Layer.CornerRadius = (nfloat)(box.CornerRadius);

        CGRect bounds = new CGRect(0, 0, box.Width, box.Width);
        Layer.Bounds = bounds;
        Layer.Frame = bounds;
    }
}
[程序集:ExportRenderer(typeof(RoundedBoxView)、typeof(RoundedBoxViewRenderer))]
命名空间TestApp.iOS
{
公共类RoundedBoxViewRenderer:BoxRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(元素!=null)
{
Layer.MasksToBounds=true;
UpdateCornerRadius(如RoundedBoxView中的新元素);
}
}
受保护的覆盖无效OnElementPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(发送方,e);
如果(e.PropertyName==CircleView.WidthProperty.PropertyName | | e.PropertyName==CircleView.HeightProperty.PropertyName)
{
UpdateCornerRadius(元素为RoundedBoxView);
}
}
void UpdateCornerRadius(圆形框视图框)
{
Layer.CornerRadius=(nfloat)(长方体CornerRadius);
CGRect边界=新的CGRect(0,0,box.Width,box.Width);
层边界=边界;
层框架=边界;
}
}
将呈现如下所示:

<Grid 
    HorizontalOptions="FillAndExpand" 
    VerticalOptions="StartAndExpand">
    <Frame 
        Grid.Row="0"
        Grid.Column="0"
        BackgroundColor="White" 
        HorizontalOptions="FillAndExpand" 
        VerticalOptions="StartAndExpand" 
        Margin="20,10,0,0"
        HeightRequest="75">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Image 
                Grid.Row="0"
                Grid.Column="0"
                Source="ellipse_1" 
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="Start" 
                HeightRequest="100" 
                WidthRequest="100" 
                BackgroundColor="White">
            </Image>
            <Image 
                Grid.Row="0"
                Grid.Column="1"
                Source="{Binding Image}" 
                HorizontalOptions="CenterAndExpand" 
                VerticalOptions="CenterAndExpand">
            </Image>
            <Label 
                Grid.Row="0"
                Grid.Column="2"
                x:Name="lbl_categories" 
                HorizontalOptions="FillAndExpand" 
                VerticalOptions="CenterAndExpand" 
                Margin="10,0,0,0" 
                TextColor="Black"
                Text="{Binding Title}" 
                LineBreakMode="WordWrap"
                HorizontalTextAlignment="Start"
                FontSize="Medium" 
                FontAttributes="Bold">
            </Label>
            <Image 
                Grid.Row="0"
                Grid.Column="3" 
                HorizontalOptions="EndAndExpand" 
                VerticalOptions="Center" 
                Source="arrow">
            </Image>
        </Grid>
    </Frame>
    <Image 
        Margin="10,10,0,0"
        Grid.Row="0"
        Grid.Column="0"
        Source="img_frm" 
        BackgroundColor="#14559a">
    </Image>
</Grid>
public class RoundedBoxView : BoxView
{
    readonly BindableProperty CornerRadiusProperty = BindableProperty.Create("CornerRadius", typeof(double), typeof(double), 0.0);

    public double CornerRadius
    {
        get { return (double)GetValue(CornerRadiusProperty); }
        set { SetValue(CornerRadiusProperty, value); }
    }
}

}

我不想这么说,但是对于您想要实现的结果,您的xaml是一场噩梦。这不仅是因为您的可视化树中有过多的元素,而且还因为您在ListView中使用的是AbsoluteLayout

尽管这在技术上是可能的,但它会导致你的应用程序性能下降,尤其是当你的ListView中填充了大量项目时

其次,为那个蓝色方块创建一个图像也是一种内存浪费,如果你的ListView包含很多条目,会导致更多的性能下降,最终可能导致Android上的OutOfMemoryException

可以将其替换为从长方体视图继承的自定义视图,并使用自定义渲染器进行渲染