MAUI MVVM xaml“找不到用于绑定的 DataContext”。更新的值未显示

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

我有两个标签字段 TabName 和 DisplayDate 以及绑定到 ViewModel 的 Collection Tasks,并且标签字段的值最初已设置,但不会出现更改。将鼠标悬停在标签绑定值上会显示“找不到绑定‘字段名称’的 DataContext”。集合已正确绑定并显示更改。

这是我的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"
             xmlns:vm="clr-namespace:DailyTasks_MVVM.ViewModels"
             xmlns:DataType="vm:DailyTasksViewModel"
             xmlns:m="clr-namespace:DailyTasks.CoreBusiness;assembly=DailyTasks.CoreBusiness"
             x:Class="DailyTasks_MVVM.Views.TaskPage"
             Title="">
    <Grid
    Padding="5"
    RowDefinitions="30, 25, *, 10, 45, 10"
    ColumnDefinitions="*">
        <Label Grid.Row="0" Grid.Column="0" Padding="0,-4" 
               FontSize="Medium" FontAttributes="Bold" 
               HorizontalOptions="Center" 
               Text="{Binding TabName}"></Label>
        <HorizontalStackLayout Grid.Row="1" Grid.Column="0">
            <Grid Padding="9,-10" RowDefinitions="25" ColumnDefinitions="315">
                <Label Text="{Binding DisplayDate}" 
                       Grid.Row="0" Grid.Column="1" 
                       HorizontalTextAlignment="Center" FontSize="Medium"></Label>
            </Grid>
        </HorizontalStackLayout>
        <CollectionView
           x:Name="TaskCollection"
           ItemsSource="{Binding Tasks}"
           Grid.Row="2"
           Grid.Column="0">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="m:cTask">
                    <StackLayout>
                        <Frame Margin="0,1,0,1">
                            <StackLayout Orientation="Vertical" Margin="-10" Spacing="0">
                                <HorizontalStackLayout>
                                    <CheckBox VerticalOptions="Start"></CheckBox>
                                    <VerticalStackLayout>
                                        <Label Margin="2,9" FontSize="Medium" Text="{Binding TaskName}" />
                                        <Label Margin="2,0" Text="{Binding HasLingered}" />
                                    </VerticalStackLayout>
                                </HorizontalStackLayout>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Button
            Grid.Row="4"
            Grid.Column="0"
            MaximumWidthRequest="50"
            MaximumHeightRequest="60"
            Scale="1.1"
            FontSize="Large"
            Command="{Binding GotoAddTaskCommand}"
            Text="+">
        </Button>        
    </Grid>
</ContentPage>

这是视图模型 DailyTasksViewModel 的属性。

namespace DailyTasks_MVVM.ViewModels
{
    public partial class DailyTasksViewModel : ObservableObject
    {
        private const string MainTab = "Main";
        private readonly IViewSpecificDateUseCase viewSpecificDateUseCase;
        [ObservableProperty]
        private DateTime currentDate;
        [ObservableProperty]
        private cTask task;
        [ObservableProperty]
        private Guid? currentTabID;
        [ObservableProperty]
        private string tabName;
        [ObservableProperty]
        public cTaskInfo taskInfo;

        public string DisplayDate
        {
            get { return CurrentDate.ToString("d"); }
        }

        public ObservableCollection<cTask> Tasks { get; set; }

        public DailyTasksViewModel(IViewSpecificDateUseCase viewSpecificDateUseCase)
        {
            this.viewSpecificDateUseCase = viewSpecificDateUseCase;
            this.Tasks = new ObservableCollection<cTask>();
            this.TabName = "Main";
            this.CurrentDate = DateTime.Now.Date;
        }


I looked at examples of setting the Source and Path in the Binding but couldn't figure out what values I needed to use.  

ex: Text="{Binding Source={x:Reference DailyTasksViewModel}, Path=TabName}"

I expect the DataContext not found message to go away and the new values display when the property values are changed.
xaml mvvm binding maui datacontext
1个回答
0
投票

根据您分享的代码,我创建了一个演示并自行尝试。但我无法在我这边重现这个问题。

您可以参考以下代码:

<?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:vm="clr-namespace:MauiApp130.ViewModels"
             xmlns:DataType="vm:DailyTasksViewModel"
             xmlns:m="clr-namespace:MauiApp130.Models"
             x:Class="MauiApp130.MainPage">    
    <ContentPage.BindingContext>
        <vm:DailyTasksViewModel></vm:DailyTasksViewModel>
    </ContentPage.BindingContext>
    <Grid
    Padding="5"
    RowDefinitions="30, 25, *, 10, 45, 10"
    ColumnDefinitions="*">
        <Label Grid.Row="0" Grid.Column="0" Padding="0,-4"
               FontSize="Medium" FontAttributes="Bold"
               HorizontalOptions="Center"
               Text="{Binding TabName}"></Label>
        <HorizontalStackLayout Grid.Row="1" Grid.Column="0">
            <Grid Padding="9,-10" RowDefinitions="25" ColumnDefinitions="315">
                <Label Text="{Binding DisplayDate}"
                       Grid.Row="0" Grid.Column="1"
                       HorizontalTextAlignment="Center" FontSize="Medium"></Label>
            </Grid>
        </HorizontalStackLayout>
        <CollectionView
           x:Name="TaskCollection"
           ItemsSource="{Binding Tasks}"
           Grid.Row="2"
           Grid.Column="0">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="m:cTask">
                    <StackLayout>
                        <Frame Margin="0,1,0,1">
                            <StackLayout Orientation="Vertical" Margin="-10" Spacing="0">
                                <HorizontalStackLayout>
                                    <CheckBox VerticalOptions="Start"></CheckBox>
                                    <VerticalStackLayout>
                                        <Label Margin="2,9" FontSize="Medium" Text="{Binding TaskName}" />
                                        <Label Margin="2,0" Text="{Binding HasLingered}" />
                                    </VerticalStackLayout>
                                </HorizontalStackLayout>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Button
            Grid.Row="4"
            Grid.Column="0"
            MaximumWidthRequest="50"
            MaximumHeightRequest="60"
            Scale="1.1"
            FontSize="Large"
            Command="{Binding GotoAddTaskCommand}"
            Text="+">
        </Button>
    </Grid>
</ContentPage>

DailyTasksViewModel.cs

public partial class DailyTasksViewModel: ObservableObject
{
    private const string MainTab = "Main";
    // private readonly IViewSpecificDateUseCase viewSpecificDateUseCase;
    [ObservableProperty]
    private DateTime currentDate;
    [ObservableProperty]
    private cTask task;
    [ObservableProperty]
    private Guid? currentTabID;
    [ObservableProperty]
    private string tabName;
    [ObservableProperty]
    public cTaskInfo taskInfo;


    public string DisplayDate
    {
        get { return CurrentDate.ToString("d"); }
    }

    public ObservableCollection<cTask> Tasks { get; set; }



    //public DailyTasksViewModel(IViewSpecificDateUseCase viewSpecificDateUseCase)
    public DailyTasksViewModel()
    {
        //this.viewSpecificDateUseCase = viewSpecificDateUseCase;
        this.Tasks = new ObservableCollection<cTask>();
        this.TabName = "Main";
        this.CurrentDate = DateTime.Now.Date;


        Tasks.Add(new cTask { TaskName = "task1", HasLingered = "yes" });
        Tasks.Add(new cTask { TaskName = "task2", HasLingered = "no" });
        Tasks.Add(new cTask { TaskName = "task3", HasLingered = "no" });
    }


    [RelayCommand]
    private void GotoAddTask()
    {

        this.TabName = "TestTabName";

        Tasks.Add(new cTask { TaskName = "task4", HasLingered = "test" });

    }
}

注:

1.我尝试在方法

TabName
上重置
GotoAddTask
的值,并且UI可以自行刷新。

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