MAUI 事件命令行为命令绑定到视图模型

问题描述 投票:0回答:1

所以我得到了 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
        }
    }
}
command maui datatemplate behavior eventtocommand
1个回答
5
投票

您可以尝试以下方法。

1.设置x:ContentPage的名称:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         ...
         x:Name="this">
  1. 设置命令绑定。然后Command绑定到ViewModel中的UnFocusedCommand

     <Editor.Behaviors>
         <toolkit:EventToCommandBehavior                            
             EventName="TextChanged"
             Command="{Binding Source={x:Reference this}, Path=BindingContext.UnFocusedCommand}">
         </toolkit:EventToCommandBehavior>               
     </Editor.Behaviors>
    

希望它对你有用。

© www.soinside.com 2019 - 2024. All rights reserved.