因此,我试图在一个视图模型的ContentView中进行数据绑定。我认为这应该很容易,因为MVVM应该是MAUI的东西,但也许我错过了一些东西。当前的解决方案基于Databinding issue
所以我有一个简单的ContentView,像这样:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModel="clr-namespace:MyProject.ViewModels"
x:Name="view"
x:Class="MyProject.Components.ContentViewComponent">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="1" Grid.Column="1"
//This NEVER picks up the value of Title >> Why??
Text="{Binding VM.Title, Source={x:Reference view}}"
FontSize="24"
FontAttributes="Bold"/>
</Grid>
</ContentView>
字符串
我的简单ContentView的Code-Behind:
using MyProject.ViewModels;
namespace MyProject.Components;
public partial class ContentViewComponent: ContentView
{
internal MyViewModel VM { get; set; }
public static readonly BindableProperty TProperty = BindableProperty.Create(nameof(T), typeof(string), typeof(MetricImperialDropdownConverter), string.Empty, propertyChanged : TitleChanged);
private static void TitleChanged(BindableObject bindable, object oldvalue, object newvalue)
{
//This fires and sets Title to T
((ContentViewComponent)bindable).VM.Title = (string)newvalue;
}
//I want to be able to set this when reusing the component
public string T
{
get => (string)GetValue(TProperty);
set => SetValue(TProperty, value);
}
public MetricImperialDropdownConverter()
{
VM = new MyViewModel();
InitializeComponent();
}
}
型
然后我有一个这样的ViewModel:
using System.ComponentModel;
namespace MyProject.ViewModels
{
public class MetricImperialDropdownConverterViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnProperyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private string _title = string.Empty;
public string Title
{
get { return _title; }
set { _title = value; OnProperyChanged(nameof(Title)); }
}
}
型
然后使用this并传入一个值:
<?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:components="clr-namespace:MyProject.Components"
x:Class="MyProject.Pages.SomePage"
x:Name="this">
<VerticalStackLayout BindingContext="{x:Reference this}">
//This works and sets T correctly
<components:ContentViewCompontent T="Here is my Title"/>
</VerticalStackLayout>
</ContentPage>
型
组件的T
设置正确。在设置T
时,我的ViewModel中的Title
属性VM
是通过PropertyChanged
事件实现的。但是UI永远不会使用Title
的值进行更新。我认为这是因为UI不响应发生在其自身上下文之外的事件。但在这种情况下我该怎么办呢??如何使UI正确更新??
2条答案
按热度按时间liwlm1x91#
从你的代码中我可以看出,你是从视图而不是从ViewModel设置Label的,坦率地说,你不应该让ContentView与ViewModel通信。它应该是可恢复的。View与ViewModel和控件通信。
我认为你混合了ContentPage(Views)和ContentViews(controls)。因此,完整的ContentView应该看起来像这样:
字符串
和xaml:
型
kmynzznz2#
根据你的代码,我实现了这个功能,可以参考下面的代码:
ContentViewComponent.xaml.cs
添加可绑定属性
YourName
。你可以把它换成你的。字符串
ContentViewComponent.xaml
型
MetricImperialDropdownConverterViewModel.cs
在这个视图模型中,我添加了一个Button命令来更新
Title
的值型
使用示例:
型