yas*_*ana 0 .net compiled-bindings maui
我创建了一个名为 的模型类Project,还创建了一个名为 的 ViewModel 类MainPageViewModel。
我想要实现的是一个具有多列的简单表。应该有一个名为“操作”的列,并且该列应该有一个按钮。
这是 XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SharpTool.UI.MainPage"
xmlns:viewmodel="clr-namespace:SharpTool.UI.ViewModels"
xmlns:models ="clr-namespace:SharpTool.UI.Models"
x:DataType="viewmodel:MainPageViewModel">
<ScrollView>
<VerticalStackLayout
Padding="10, 10">
<Border MinimumHeightRequest="50" StrokeThickness ="0.5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border StrokeThickness="0.1" Grid.Column="0">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="Id" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="1">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="Name" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="2">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="Discription" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="3">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="Version" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="4">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="Action" TextColor="Blue"/>
</Border>
</Grid>
</Border>
<CollectionView ItemsSource="{Binding Projects}" >
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Project">
<Border MinimumHeightRequest="50" StrokeThickness ="0.5" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border StrokeThickness="0.1" Grid.Column="0">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="{Binding Id}" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="1">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="{Binding Name}" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="2">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="{Binding Description}" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="3">
<Label HorizontalOptions="Center" VerticalOptions="Center" FontFamily="icon" FontSize="15" Text="{Binding Version}" TextColor="Blue"/>
</Border>
<Border StrokeThickness="0.1" Grid.Column="4">
<Button
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Command="{Binding GetProjectByCommand}"
CommandParameter="2"
HorizontalOptions="Center" />
</Border>
</Grid>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Run Code Online (Sandbox Code Playgroud)
我设法实现了 UI 代码,但遇到了问题。当我设置 时x:DataType="models:Project",DataTemplate我无法将 ViewModel 方法绑定到按钮或任何其他组件。
它给了我一个错误:
绑定:在“SharpTool.UI.Models.Project”上找不到属性“GetProjectByCommand”。
如果我删除这部分:
Command="{Binding GetProjectByCommand}"在 内的按钮中Grid,那么项目将构建并运行,不会出现任何问题。
这是视图模型代码:
[INotifyPropertyChanged]
public partial class MainPageViewModel
{
[ObservableProperty]
ObservableCollection<Project> projects = new();
[ObservableProperty]
public bool isBusy = false;
public ICommand GetProjectByCommand { private set; get; }
public MainPageViewModel()
{
projects.Add(new Project { Id = 1, Name = "Project 1 Name", Description = "Project 1 Description", Version = "1.0" });
projects.Add(new Project { Id = 2, Name = "Project 2 Name", Description = "Project 2 Description", Version = "1.0" });
projects.Add(new Project { Id = 3, Name = "Project 3 Name", Description = "Project 3 Description", Version = "1.0" });
projects.Add(new Project { Id = 4, Name = "Project 1 Name", Description = "Project 1 Description", Version = "1.0" });
projects.Add(new Project { Id = 5, Name = "Project 2 Name", Description = "Project 2 Description", Version = "1.0" });
projects.Add(new Project { Id = 6, Name = "Project 3 Name", Description = "Project 3 Description", Version = "1.0" });
projects.Add(new Project { Id = 7, Name = "Project 1 Name", Description = "Project 1 Description", Version = "1.0" });
projects.Add(new Project { Id = 8, Name = "Project 2 Name", Description = "Project 2 Description", Version = "1.0" });
projects.Add(new Project { Id = 9, Name = "Project 3 Name", Description = "Project 3 Description", Version = "1.0" });
projects.Add(new Project { Id = 10, Name = "Project 3 Name", Description = "Project 3 Description", Version = "1.0" });
GetProjectByCommand = new Command<string>(GetProjectById);
}
private void GetProjectById(string id)
{
//query project list
}
}
Run Code Online (Sandbox Code Playgroud)
那么,如何将该GetProjectById方法绑定到网格内的按钮?
这种事经常发生。这里的问题是,每当您处于显示项目的控件中时,数据绑定范围都会发生变化。
对于您的整页,视图模型是您的MainPageViewModel. 然后你就有了一个从你的属性CollectionView中读取的内容。到目前为止,一切都很好。ProjectsMainPageViewModel
但是,在您的内部CollectionView,尤其是在您的内部ItemTemplate,您的范围不再局限于页面的其余部分,但绑定上下文现在是您在其中放置的任何项目的类型(在您的情况下)Project。您还可以看到这一点,因为您必须指定<DataTemplate x:DataType="models:Project">哪个应该向您表明您现在正在查看Project对象,而不是不再查看对象MainPageViewModel。
有多种选择可以解决这个问题。最明显但不一定最好的是将 添加GetProjectByCommand到您的Project对象中。然而,从技术上讲,这可能是您的责任MainPageViewModel。
另一个选择是更改您的绑定以确保它MainPageViewModel再次查看您的。为此,请更改此行:
<Button
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Command="{Binding GetProjectByCommand}"
CommandParameter="2"
HorizontalOptions="Center" />
Run Code Online (Sandbox Code Playgroud)
对此:
<Button
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Command="{Binding GetProjectByCommand, Source={x:Reference mainPage.BindingContext}}"
CommandParameter="2"
HorizontalOptions="Center" />
Run Code Online (Sandbox Code Playgroud)
为了使其正常工作,请确保将该x:Name="mainPage"属性添加到您的ContentPage节点。
其作用是将绑定的源设置为mainPage.BindingContext您的MainPageViewModel.
有关此内容的更多信息也可以在我的视频中找到:https://www.youtube.com/watch ?v=Or_qn8i8jVM
我刚刚注意到在我的视频中我使用了不同的语法:
<Button
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Command="{Binding Path=BindingContext.GetProjectByCommand, Source={Reference mainPage}}"
CommandParameter="2"
HorizontalOptions="Center" />
Run Code Online (Sandbox Code Playgroud)
本质上是相同的,但写法不同。