如何将网格宽度(列表项)绑定到xamarin表单中的通用视图模型中的属性?

如何将网格宽度(列表项)绑定到xamarin表单中的通用视图模型中的属性?,xamarin,mvvm,xamarin.forms,data-binding,Xamarin,Mvvm,Xamarin.forms,Data Binding,我有一个GridViewCard,在我的Xamarin表单应用程序的多个屏幕中用作数据模板。所有这些页面都有一个从基本视图模型扩展而来的视图模型。是否可以将GridCard的宽度绑定到基本视图模型中的GridLength属性,而不依赖于使用它的页面/列表 GridViewCard: <Grid xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml

我有一个GridViewCard,在我的Xamarin表单应用程序的多个屏幕中用作数据模板。所有这些页面都有一个从基本视图模型扩展而来的视图模型。是否可以将GridCard的宽度绑定到基本视图模型中的GridLength属性,而不依赖于使用它的页面/列表

GridViewCard:

<Grid xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:i18n="clr-namespace:ScholarApp.Assets.Extensions;assembly=ScholarApp" xmlns:controls="clr-namespace:ScholarApp.Assets.Controls" xmlns:Pancake="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView" xmlns:converters="clr-namespace:ScholarApp.Assets.Converters" x:Class="ScholarApp.Assets.Templates.GridViewCard" RowSpacing="10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="{OnIdiom Phone='20,10,0,20',Tablet='30,15,0,30'}">
    <Grid.RowDefinitions>
        <RowDefinition Height="{OnIdiom Phone='200',Tablet='280'}" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{"**this value should be dynamically bound to the page in which it is being used**" }" />
    </Grid.ColumnDefinitions>

</Grid>

多页中的多个用例

一页中的代码段:

<StackLayout Style="{DynamicResource Default}" Padding="0,5,0,0" IsVisible="{Binding IsViewVisible}">
                <flv:FlowListView x:Name="ExploreGridView" IsVisible="{Binding IsGridLayout}" BackgroundColor="Transparent" Margin="{OnIdiom Phone='0,0,20,0',Tablet='0,0,30,0'}" FlowColumnCount="{OnIdiom Phone='2',Tablet='3'}" SeparatorVisibility="None" HasUnevenRows="true" FlowItemsSource="{Binding HandpickedList}" VerticalScrollBarVisibility="Never">
                    <flv:FlowListView.FlowColumnTemplate>
                        <DataTemplate>
                            <templates:GridViewCard />
                        </DataTemplate>
                    </flv:FlowListView.FlowColumnTemplate>
                </flv:FlowListView>
            </StackLayout>

来自另一页的代码段:

<ScrollView VerticalScrollBarVisibility="Never"
                HorizontalScrollBarVisibility="Never"
                Orientation="Horizontal">
        <StackLayout Padding="{DynamicResource ExploreStkPadding20}"
                     Orientation="Horizontal"
                     Spacing="{OnIdiom Phone='20',Tablet='30'}"
                     HeightRequest="{DynamicResource HandpickedHeight}"
                     BindableLayout.ItemsSource="{Binding ViewData}">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <templates:GridViewCard />
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </ScrollView>

要获得此功能,您需要几件事情:

首先,将名称(
x:name
)添加到
GridViewCard
XAML文件中的
Grid
。稍后您将使用它

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"    
      x:Class="SQDictionary.GridViewCard"
      RowSpacing="10"
      x:Name="LeGrid"
      HorizontalOptions="FillAndExpand"
      BackgroundColor="BlueViolet"
      VerticalOptions="FillAndExpand"
      Padding="{OnIdiom Phone='20,10,0,20',Tablet='30,15,0,30'}">
此代码将公开UserControl中的
GridLength
属性,并在属性更改时更新网格列定义(宽度)

此代码仅设置第一列的宽度(如您所示,只有一列)。但是,如果要添加更多列并使用相同的值,只需迭代
ColumnDefinition
集合即可

3:无论何时使用
GridViewCard
控件,您都可以访问我们刚刚创建的属性
GridWidth
,并设置一个值

<DataTemplate>
    <templates:GridViewCard GridWidth="130" />
</DataTemplate>
现在,以流程表为例:

您将使用流列表中的名称(
x:name
)访问BindingContext,然后访问属性的值

<flv:FlowListView x:Name="ExploreGridView" 
                IsVisible="{Binding IsGridLayout}" 
                BackgroundColor="Transparent" 
                Margin="{OnIdiom Phone='0,0,20,0',Tablet='0,0,30,0'}" 
                FlowColumnCount="{OnIdiom Phone='2',Tablet='3'}" 
                SeparatorVisibility="None"                 
                HasUnevenRows="true" 
                FlowItemsSource="{Binding HandpickedList}" 
                VerticalScrollBarVisibility="Never">
    <flv:FlowListView.FlowColumnTemplate>
        <DataTemplate>
            <templates:GridViewCard GridWidth="{Binding BindingContext.GridColumnLength, Source={x:Reference ExploreGridView}}" />
        </DataTemplate>
    </flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>

现在,当在具有访问权限的ViewModels的
GridColumnLength
属性上设置值时,将触发对
GridViewCard
自定义控件上的Grid.Column.Width的更改


希望这有帮助。-

但是您希望所有列都有一个宽度值,还是希望将ColumnWidth1、ColumnWidth2等值绑定到网格的不同列?对于当前场景,网格将始终只有一列,更改只需应用于该宽度。无论如何,额外的信息也很受欢迎。我没有使用x:Name=“LeGrid”,而是像gridView.ColumnDefinitions?.ElementAtOrDefault(0)一样直接访问它@MidhunKumar是正确的,因为gridView已经是一个网格,很好的捕获!
private double _gridColumnLength;
public double GridColumnLength
{
    get => _gridColumnLength;
    set
    {
       //Don't know how you are handling the **Set** and/or Raising of property changes.
      // Modify accordingly (if required)
        _gridColumnLength = value;
        RaisePropertyChanged(nameof(GridColumnLength));
    }
}
<flv:FlowListView x:Name="ExploreGridView" 
                IsVisible="{Binding IsGridLayout}" 
                BackgroundColor="Transparent" 
                Margin="{OnIdiom Phone='0,0,20,0',Tablet='0,0,30,0'}" 
                FlowColumnCount="{OnIdiom Phone='2',Tablet='3'}" 
                SeparatorVisibility="None"                 
                HasUnevenRows="true" 
                FlowItemsSource="{Binding HandpickedList}" 
                VerticalScrollBarVisibility="Never">
    <flv:FlowListView.FlowColumnTemplate>
        <DataTemplate>
            <templates:GridViewCard GridWidth="{Binding BindingContext.GridColumnLength, Source={x:Reference ExploreGridView}}" />
        </DataTemplate>
    </flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>