所以我得到了 ContentPage.Resources,其中我为 BindableLayout 定义了 DataTemplate。我需要将此 DataTemplate 中的 Unfocused 编辑器事件绑定到我的 ViewModel 中继命令。但我不能像这样
Command="{Binding UnfocusedCommand}
这样做,因为我为此 DataTemplate 定义了数据类型。所以我尝试以这种方式进行操作Command="{Binding UnfocusedCommand, Source={RelativeSource AncestorType={x:Type viewModels:TestDetailsViewModel}}}
,并且这种方式Command="{Binding Source={RelativeSource AncestorType={x:Type viewModel:TestDetailsViewModel}}, Path=UnfocusedCommand}"
也不起作用,并给我错误“由于对象的当前状态,操作无效”。如果没有这种行为,一切都可以正常工作,所以请告诉我如何正确执行此操作以及我做错了什么。
我的观点:
<?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"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="Bibliomatic_MAUI_App.Views.TestDetailsView"
xmlns:models="clr-namespace:Bibliomatic_MAUI_App.Models"
xmlns:viewModel="clr-namespace:Bibliomatic_MAUI_App.ViewModels"
xmlns:selectors="clr-namespace:Bibliomatic_MAUI_App.Selectors"
x:DataType="viewModel:TestDetailsViewModel"
Title="TestDetailsView">
<ContentPage.Resources>
<!-- Problem with that data template -->
<DataTemplate x:Key="OneAnswerQuestion" x:DataType="models:TestAnswerResponce">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<RadioButton GroupName="TestAnswersGroup" Grid.Column="0"/>
<Editor AutoSize="TextChanges" Placeholder="Enter qustion answer" Grid.Column="1">
<Editor.Behaviors>
<toolkit:EventToCommandBehavior
EventName="TextChanged"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewModel:TestDetailsViewModel}}, Path=UnfocusedCommand}"/>
</Editor.Behaviors>
</Editor>
</Grid>
</DataTemplate>
<DataTemplate x:Key="MultipleAnswerQuestion" x:DataType="models:TestAnswerResponce">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"/>
<Editor Grid.Column="1" AutoSize="TextChanges" Placeholder="Enter qustion answer"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="PairsQuestion" x:DataType="models:TestAnswerResponce">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Editor Grid.Column="0" AutoSize="TextChanges" Placeholder="Enter qustion"/>
<Editor Grid.Column="1" AutoSize="TextChanges" Placeholder="Enter answer"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="OpenEndedQuestion" x:DataType="models:TestQuestionResponce">
<Editor AutoSize="TextChanges" Placeholder="Enter qustion answer"/>
</DataTemplate>
<selectors:TestQuestionsDataTemplateSelector x:Key="TestAnswerTemplate"
OneAnswerQuestion="{x:StaticResource OneAnswerQuestion}"
MultipleAnswerQuestion="{x:StaticResource MultipleAnswerQuestion}"
PairsQuestion="{x:StaticResource PairsQuestion}"
OpenEndedQuestion="{x:StaticResource OpenEndedQuestion}"/>
</ContentPage.Resources>
<StackLayout>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border StrokeThickness="3.5">
<Border.StrokeShape>
<RoundRectangle CornerRadius="10"></RoundRectangle>
</Border.StrokeShape>
<Picker Grid.Column="0" SelectedItem="{Binding SelectedQuestionType}" ItemsSource="{Binding TestQuestionTypes}"/>
</Border>
<Button Grid.Column="1" Margin="0,20" Text="Add test question" Command="{Binding AddTestQuestionCommand}"/>
</Grid>
<CollectionView ItemsSource ="{Binding TestQuestions}"
VerticalOptions="FillAndExpand"
SelectionMode="None"
x:Name="TestsCollectionView">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:TestQuestionResponce">
<StackLayout Margin="0,20">
<Entry Placeholder="Enter your question"/>
<StackLayout BindableLayout.ItemsSource="{Binding TestAnswers}" BindableLayout.ItemTemplateSelector="{StaticResource TestAnswerTemplate}"/>
<Button Text="Add test answer" Command="{Binding Source={RelativeSource AncestorType={x:Type viewModel:TestDetailsViewModel}}, Path=AddTestAnswerCommand}"
CommandParameter="{Binding .}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
我的视图模型:
using Bibliomatic_MAUI_App.Models;
using Bibliomatic_MAUI_App.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Syncfusion.Maui.DataSource.Extensions;
using System.Collections.ObjectModel;
namespace Bibliomatic_MAUI_App.ViewModels
{
[QueryProperty(nameof(Test), "Test")]
public partial class TestDetailsViewModel : ObservableObject
{
public ObservableCollection<TestQuestionResponce> TestQuestions { get; set; }
public List<TestQuestionType> TestQuestionTypes { get; set; }
[ObservableProperty]
public TestResponce test;
[ObservableProperty]
public TestQuestionType selectedQuestionType;
private readonly TestService testSerice;
public TestDetailsViewModel(TestService testService)
{
this.testSerice = testService;
TestQuestions = new ObservableCollection<TestQuestionResponce>();
TestQuestionTypes = Enum.GetValues(typeof(TestQuestionType))
.Cast<TestQuestionType>()
.ToList();
}
[RelayCommand]
public void AddTestQuestion()
{
TestQuestions.Add(new TestQuestionResponce
{
Question = string.Empty,
TestId = Test.Id,
Test = Test,
TestQuestionType = SelectedQuestionType,
TestAnswers = new ObservableCollection<TestAnswerResponce>(),
});
}
[RelayCommand]
public void AddTestAnswer(object parameter)
{
var selectedQuestion = parameter as TestQuestionResponce;
selectedQuestion.TestAnswers.Add(new TestAnswerResponce
{
Answer = string.Empty,
TestQuestionId = selectedQuestion.Id,
TestQuestion = selectedQuestion,
});
}
[RelayCommand]
public async void Unfocused()
{
//Some work
}
}
}
您可以尝试以下方法。
1.设置x:ContentPage的名称:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
...
x:Name="this">
设置命令绑定。然后Command绑定到ViewModel中的UnFocusedCommand
<Editor.Behaviors>
<toolkit:EventToCommandBehavior
EventName="TextChanged"
Command="{Binding Source={x:Reference this}, Path=BindingContext.UnFocusedCommand}">
</toolkit:EventToCommandBehavior>
</Editor.Behaviors>
希望它对你有用。