Chr*_*ris 1 xaml binding mvvm maui .net-maui
我正在学习了解 .NET MAUI 的 XAML 中的绑定机制如何工作。我假设这对于所有 XAML 项目、WPF、MAUI 等都是相同的。
\n最后是整个 XAML。
\n这个 XAML 工作正常:
\n<Button WidthRequest="150" Text="Add Activity" \n Command="{Binding AddActivityEntityCommand}"\n IsEnabled="{Binding IsNotBusy}"\n Grid.Row="2"\n Margin="8"/>\nRun Code Online (Sandbox Code Playgroud)\n这是因为 Button 是 ContentPage 的一部分,它被x:DataType设置为MainPageViewModel,这是命令所在的位置吗?
Binding 设置为AddActivityEntityCommand,而实际方法签名为\n async Task AddActivityEntityAsync()。这是如何解决的?因为它显然与名称不匹配,但它有效。其工作/被认可的方法签名要求是什么?
另一方面,这并不像开箱即用那么简单:
\n<Label HorizontalOptions="End" TextColor="Red" Padding="0,0,10,0" Text="" \n IsVisible="{Binding IsSynchronized}">\n <Label.GestureRecognizers>\n <TapGestureRecognizer \n Command="{Binding Source={x:Type viewmodel:MainPageViewModel},\n Path=DeleteActivityCommand}" />\n </Label.GestureRecognizers>\n </Label>\nRun Code Online (Sandbox Code Playgroud)\nCommand="{Binding DeleteActivityCommand}不起作用,因为<DataTemplate x:DataType="model:ActivityEntity">我假设它从 派生其 Path,这是数据对象,而不是命令实际所在的 ViewModel。Command="{Binding Source={x:Type viewmodel:MainPageViewModel}, Path=DeleteActivityCommand}", CollectionView 显示为空,并且在加载视图时抛出未处理的异常:\n\nSystem.Reflection.TargetException:对象与目标类型不匹配。
\n
async Task DeleteActivityAsync()我缺少什么?
\n<?xml version="1.0" encoding="utf-8" ?>\n<ContentPage\n x:Class="OnesieMobile.View.MainPage"\n xmlns="http://schemas.microsoft.com/dotnet/2021/maui"\n xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"\n xmlns:model="clr-namespace:OnesieMobile.Model"\n xmlns:viewmodel="clr-namespace:OnesieMobile.ViewModel"\n x:DataType="viewmodel:MainPageViewModel"\n Title="{Binding Title}">\n <Grid\n ColumnDefinitions="*"\n RowDefinitions="20,50,50,*"\n RowSpacing="0">\n <Label HorizontalOptions="End" Margin="10,0,10,0" Text="{Binding CurrentDateTime}" Grid.Row="0"/>\n <Entry Margin="10,0,10,0" \n Grid.Row="1" x:Name="entryNewActivity" \n Placeholder="New Activityssss" HeightRequest="30" Text="{Binding NewActivityTitle}" />\n\n <Button WidthRequest="150" Text="Add Activity" \n Command="{Binding AddActivityEntityCommand}"\n IsEnabled="{Binding IsNotBusy}"\n Grid.Row="2"\n Margin="8"/>\n\n <CollectionView\n Grid.Row="3"\n ItemsSource="{Binding ActivityEntities}"\n SelectionMode="None">\n <CollectionView.ItemTemplate>\n <DataTemplate x:DataType="model:ActivityEntity">\n <Grid Padding="10,0,10,0">\n <Frame Style="{StaticResource CardView}">\n <Grid ColumnDefinitions="*,30,50">\n <StackLayout Padding="10,5,0,0" Grid.Column="0">\n <Label Text="{Binding Title}" />\n </StackLayout>\n <StackLayout Padding="10,5,0,0" Grid.Column="1">\n <Label HorizontalOptions="End" TextColor="Red"\n Padding="0,0,10,0" Text="" IsVisible="{Binding IsSynchronized}" >\n <Label.GestureRecognizers>\n <TapGestureRecognizer\n Command="{Binding Source={x:Type viewmodel:MainPageViewModel},\n Path=DeleteActivityCommand}" />\n </Label.GestureRecognizers>\n </Label>\n </StackLayout>\n <StackLayout Padding="10,5,0,0" Grid.Column="2">\n <Label HorizontalOptions="End" \n Padding="0,0,10,0" Text="\xe2\x9c\x94" IsVisible="{Binding IsSynchronized}" />\n </StackLayout>\n </Grid>\n </Frame>\n </Grid>\n </DataTemplate>\n </CollectionView.ItemTemplate>\n </CollectionView>\n <ActivityIndicator IsVisible="{Binding IsBusy}"\n IsRunning="{Binding IsBusy}"\n HorizontalOptions="FillAndExpand"\n VerticalOptions="CenterAndExpand"\n Grid.RowSpan="3"\n Grid.ColumnSpan="2"/>\n\n </Grid>\n</ContentPage>\nRun Code Online (Sandbox Code Playgroud)\n更新:
\nMainPageViewModel.cs 包含这些命令
[ICommand]\nasync Task DeleteActivityAsync()\n{\n}\n\n\n[ICommand]\nasync Task AddActivityEntityAsync()\n{\n}\nRun Code Online (Sandbox Code Playgroud)\n
在项目模板内,有多种方法可以引用原始 BindingContext。我喜欢通过从集合本身获取它来做到这一点:
<CollectionView x:Name="myCollection" ...>
...
<CollectionView.ItemTemplate>
...
Command="{Binding Source={x:Reference myCollection},
Path=BindingContext.DeleteActivityCommand}" />
Run Code Online (Sandbox Code Playgroud)
未来待定:
我不喜欢执行代码中不存在的命令名称。希望最终有一种方法可以在 ICommand 属性中指定命令名称,以使其显而易见:
// This won't work today.
[ICommand Name="DeleteActivityCommand"]
...
Run Code Online (Sandbox Code Playgroud)
现在,我们必须学习 的[ICommand]神奇命名规则,它似乎是“Async从末尾删除(如果存在);添加Command到末尾”。
| 归档时间: |
|
| 查看次数: |
2404 次 |
| 最近记录: |