xaml - 如何将 ContentView 中的 CommandParameter 绑定到 Xamarin Forms 中父 ContentPage 中的元素
问题描述
我有一个父 ContentPage,其中有几个 ContentView 在单独的文件中。我试图将父 ContentView 中的元素作为引用传递给其中一个视图中的 CommandParameter,下面是我到目前为止的代码。
这是父 ContentPage
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="Acies.NitroT.Views.Shop.RefillPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:base="clr-namespace:Acies.NitroT.ViewModels.Base;assembly=Acies.NitroT.Mobile.Shared"
xmlns:behaviors="clr-namespace:Acies.NitroT.Behaviors;assembly=Acies.NitroT.Mobile.Shared"
xmlns:control="clr-namespace:Acies.NitroT.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:homeViews="clr-namespace:Acies.NitroT.Views.Home"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tab="clr-namespace:Syncfusion.XForms.TabView;assembly=Syncfusion.SfTabView.XForms"
xmlns:transViews="clr-namespace:Acies.NitroT.Views.Transaction"
Title="Gas Refill"
Padding="0"
base:ViewManager.AutoWireViewModel="true"
BackgroundColor="{DynamicResource Gray-White}"
NavigationPage.HasNavigationBar="False"
Visual="Material"
mc:Ignorable="d">
<ContentPage.Content>
<RelativeLayout Padding="0">
<RelativeLayout.Margin>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 40, 0, 0" />
</OnPlatform>
</RelativeLayout.Margin>
<Grid
Padding="0"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=1}"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<!--#region Google Map [Row:0] Pins="{Binding Pins}"-->
<control:GoogleMapView
x:Name="Map"
Grid.Row="0"
Grid.RowSpan="2"
Margin="0"
Padding="0"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
<!--#endregion-->
<!--#region Search Control [Row:1]-->
<Grid
Grid.Row="1"
Margin="20"
VerticalOptions="Start">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<!--#region Search Bar-->
<homeViews:SearchBarView Grid.Row="0" Padding="0" />
<!--#endregion-->
<!--#region Chip Group-->
<homeViews:AddressChipView Grid.Row="1" />
<!--#endregion-->
<!--#region Search Results View-->
<homeViews:SearchResultsView Grid.Row="2" Padding="0" />
<!--#endregion-->
</Grid>
<!--#endregion-->
<!--#region Bottom Control [Row:2]-->
<homeViews:CommandButtonsView
Grid.Row="1"
Margin="0,0,0,10"
VerticalOptions="End" />
<!--#endregion-->
</Grid>
</RelativeLayout>
</ContentPage.Content>
这是我尝试将control:GoogleMapView
withx:Name="Map"
作为传递的 ContentPageCommandParameter
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="Acies.NitroT.Views.Home.AddressChipView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:behaviors="clr-namespace:Acies.NitroT.Behaviors"
xmlns:buttons="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:Acies.NitroT.Controls;assembly=Acies.NitroT.Mobile.Shared"
mc:Ignorable="d">
<ContentView.Content>
<!--#region Chip Group-->
<StackLayout Grid.Row="1">
<ScrollView
Margin="{StaticResource ChipMargin}"
HorizontalScrollBarVisibility="Never"
Orientation="Horizontal">
<buttons:SfChipGroup
ChipPadding="2,0,0,0"
Command="{Binding SelectedAddressCommand}"
DisplayMemberPath="Nickname"
ItemsSource="{Binding AddressItems}"
SelectedChipBackgroundColor="{StaticResource BlueDark}"
SelectedItem="{Binding SelectedAddress}"
ShowIcon="True"
Type="Choice">
<buttons:SfChipGroup.Behaviors>
<behaviors:EventToCommandBehavior
Command="{Binding AddressSelectionChangedCommand}"
CommandParameter="{Binding Source={x:RelativeSource Mode=FindAncestor, AncestorType={x:Type controls:GoogleMapView}}, Path=.}"
EventName="SelectionChanged" />
</buttons:SfChipGroup.Behaviors>
</buttons:SfChipGroup>
</ScrollView>
</StackLayout>
<!--#endregion-->
</ContentView.Content>
上面的代码给了我以下错误:
09-29 10:52:19.447 I/MonoDroid(25814): UNHANDLED EXCEPTION:
09-29 10:52:19.449 I/MonoDroid(25814): System.InvalidOperationException: Operation is not valid due to the current state of the object.
09-29 10:52:19.449 I/MonoDroid(25814): at Xamarin.Forms.Binding.ApplyRelativeSourceBinding (Xamarin.Forms.BindableObject targetObject, Xamarin.Forms.BindableProperty targetProperty) [0x00041] in D:\a\1\s\Xamarin.Forms.Core\Binding.cs:153
09-29 10:52:19.449 I/MonoDroid(25814): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
09-29 10:52:19.449 I/MonoDroid(25814): at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <7d2292394f8c488b97f5bc2a0ac0240d>:0
09-29 10:52:19.449 I/MonoDroid(25814): at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <7d2292394f8c488b97f5bc2a0ac0240d>:0
09-29 10:52:19.449 I/MonoDroid(25814): at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <7d2292394f8c488b97f5bc2a0ac0240d>:0
09-29 10:52:19.449 I/MonoDroid(25814): at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
我怎样才能达到预期的结果。
解决方案
您可以检查以下代码
在 AddressChipView.xaml
由于您使用过 Custom ContentView ,因此您需要使用可绑定属性来绑定ContentView和Parent ContentPage中的元素之间的值
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="Acies.NitroT.Views.Home.AddressChipView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:behaviors="clr-namespace:Acies.NitroT.Behaviors"
xmlns:buttons="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:Acies.NitroT.Controls;assembly=Acies.NitroT.Mobile.Shared"
mc:Ignorable="d"
x:Name="ChipView" // set the name of AddressChipView
>
<buttons:SfChipGroup
ChipPadding="2,0,0,0"
Command="{Binding Source={x:Reference ChipView}, Path=SelectedAddressCommand}"
//...
SelectedItem="{Binding Source={x:Reference ChipView}, Path=SelectedAddress}"
ShowIcon="True"
Type="Choice">
<buttons:SfChipGroup.Behaviors>
<behaviors:EventToCommandBehavior
Command="{Binding Source={x:Reference ChipView}, Path=AddressSelectionChangedCommand}"
CommandParameter="{Binding Source={x:Reference ChipView}, Path=CurrentMapView}"
EventName="SelectionChanged" />
</buttons:SfChipGroup.Behaviors>
</buttons:SfChipGroup>
在 AddressChipView.xaml.cs
public static readonly BindableProperty AddressSelectionChangedCommandProperty =
BindableProperty.Create(nameof(AddressSelectionChangedCommand), typeof(ICommand), typeof(AddressChipView));
public ICommand AddressSelectionChangedCommand
{
get => (ICommand)GetValue(AddressSelectionChangedCommandProperty );
set => SetValue(AddressSelectionChangedCommandProperty , value);
}
public static BindableProperty CurrentMapViewProperty =
BindableProperty.Create(nameof(CurrentMapView), typeof(object), typeof(AddressChipView));
public object CurrentMapView
{
get => (object)GetValue(CurrentMapViewProperty );
set => SetValue(CurrentMapViewProperty , value);
}
//... other bindable property
现在您可以在 ContentPage 中绑定它
<homeViews:AddressChipView Grid.Row="1" AddressSelectionChangedCommand={Binding xxxCommand} CurrentMapView = {Binding Source={x:Reference Map}, Path=.} />
推荐阅读
- html - 如何在 CSS 中调整这些图像的大小?
- continuous-integration - Bitbucket管道中的树稳定计时器?
- sql-server - SSIS 部署的包无法将驱动器标记映射到网络共享文件夹
- python - 使用 Flask API 而不是 render_template
- docker - 使用 Docker 将现有 Prestashop 部署到服务器
- r - R中矩阵的条件和减法
- amazon-web-services - 使用代码授予的简单 Cognito 用户身份验证不起作用
- tensorflow - tensorflow keras 保存和加载模型
- sql-server - (T-SQL) 夏令时是否发生在最后一小时?
- c# - C# PasswordDeriveBytes:似乎 Salt 无关紧要