我正在學習了解系結機制如何在 XAML for .NET MAUI 中作業。我假設這對于所有 XAML 專案、WPF、MAUI 等都是相同的。
最后是整個 XAML。
此 XAML 作業正常:
<Button WidthRequest="150" Text="Add Activity"
Command="{Binding AddActivityEntityCommand}"
IsEnabled="{Binding IsNotBusy}"
Grid.Row="2"
Margin="8"/>
這樣做的原因是因為 Button 是 ContentPage 的一部分,它
x:DataType設定為MainPageViewModel,這是命令所在的位置?Binding 設定為
AddActivityEntityCommand,而實際的方法簽名是async Task AddActivityEntityAsync()。這是如何解決的?因為它顯然與名稱不匹配,但它有效。什么是方法簽名要求這個作業/被識別?
另一方面,這不僅僅開箱即用:
<Label HorizontalOptions="End" TextColor="Red" Padding="0,0,10,0" Text="??"
IsVisible="{Binding IsSynchronized}">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={x:Type viewmodel:MainPageViewModel},
Path=DeleteActivityCommand}" />
</Label.GestureRecognizers>
</Label>
- 在這種情況下,添加
Command="{Binding DeleteActivityCommand}不起作用,因為它派生了它的路徑<DataTemplate x:DataType="model:ActivityEntity">,我假設它是資料物件,而不是命令實際所在的 ViewModel。 - 這里的問題是,只要我輸入此 XAML
Command="{Binding Source={x:Type viewmodel:MainPageViewModel}, Path=DeleteActivityCommand}", CollectionView 就會顯示為空,并且在加載視圖時會引發未處理的例外:
System.Reflection.TargetException:物件與目標型別不匹配。
- 此命令的方法簽名是這個
async Task DeleteActivityAsync()
我錯過了什么?
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="OnesieMobile.View.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:model="clr-namespace:OnesieMobile.Model"
xmlns:viewmodel="clr-namespace:OnesieMobile.ViewModel"
x:DataType="viewmodel:MainPageViewModel"
Title="{Binding Title}">
<Grid
ColumnDefinitions="*"
RowDefinitions="20,50,50,*"
RowSpacing="0">
<Label HorizontalOptions="End" Margin="10,0,10,0" Text="{Binding CurrentDateTime}" Grid.Row="0"/>
<Entry Margin="10,0,10,0"
Grid.Row="1" x:Name="entryNewActivity"
Placeholder="New Activityssss" HeightRequest="30" Text="{Binding NewActivityTitle}" />
<Button WidthRequest="150" Text="Add Activity"
Command="{Binding AddActivityEntityCommand}"
IsEnabled="{Binding IsNotBusy}"
Grid.Row="2"
Margin="8"/>
<CollectionView
Grid.Row="3"
ItemsSource="{Binding ActivityEntities}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:ActivityEntity">
<Grid Padding="10,0,10,0">
<Frame Style="{StaticResource CardView}">
<Grid ColumnDefinitions="*,30,50">
<StackLayout Padding="10,5,0,0" Grid.Column="0">
<Label Text="{Binding Title}" />
</StackLayout>
<StackLayout Padding="10,5,0,0" Grid.Column="1">
<Label HorizontalOptions="End" TextColor="Red"
Padding="0,0,10,0" Text="??" IsVisible="{Binding IsSynchronized}" >
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={x:Type viewmodel:MainPageViewModel},
Path=DeleteActivityCommand}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
<StackLayout Padding="10,5,0,0" Grid.Column="2">
<Label HorizontalOptions="End"
Padding="0,0,10,0" Text="?" IsVisible="{Binding IsSynchronized}" />
</StackLayout>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ActivityIndicator IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
Grid.RowSpan="3"
Grid.ColumnSpan="2"/>
</Grid>
</ContentPage>
更新:
MainPageViewModel.cs 包含這些命令
[ICommand]
async Task DeleteActivityAsync()
{
}
[ICommand]
async Task AddActivityEntityAsync()
{
}
uj5u.com熱心網友回復:
在專案模板中,有幾種方法可以參考原始的 BindingContext。我喜歡通過從集合本身獲取它來做到這一點:
<CollectionView x:Name="myCollection" ...>
...
<CollectionView.ItemTemplate>
...
Command="{Binding Source={x:Reference myCollection},
Path=BindingContext.DeleteActivityCommand}" />
未來待定:
我不喜歡實作代碼中任何地方都不存在的命令名稱。希望最終會有一種方法可以在 ICommand 屬性中指定命令名稱,以使其顯而易見:
// This won't work today.
[ICommand Name="DeleteActivityCommand"]
...
現在,我們必須學習[ICommand]的神奇命名規則,似乎是“Async從末尾洗掉(如果存在);添加Command到末尾”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/485878.html
