绑定不更新 WinUI 3

Tri*_*and 3 data-binding xaml mvvm uwp winui-3

我将 WinUI 与 microsoft MVVM 工具包结合使用。但是,我在绑定方面遇到了一些问题,并且无法找出问题所在。

ViewModel 和 ViewModel 中使用的模型属于 observableObject 类型。命令被触发,数据被获取。但是,除非我更改 xaml 并热重新加载更改,否则绑定不会在 UI 中显示结果。

我的页面:

<Page
x:Class="ThrustmasterGuide.Pages.WheelBasePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ThrustmasterGuide.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:ThrustmasterGuide.DataAccess.Context.Model"
xmlns:wheelbase="using:ThrustmasterGuide.ViewModel.Wheelbase"
xmlns:xaml="using:ABI.Microsoft.UI.Xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:converters="using:ThrustmasterGuide.Converters"
xmlns:wheelBase="using:ThrustmasterGuide.Model.WheelBase"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance wheelbase:WheelBaseViewModel, IsDesignTimeCreatable=True}">
<Page.Resources>
    <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
    <converters:InvertBoolToVisibilityConverter x:Key="InvertBoolToVisibilityConverter" />
</Page.Resources>
<interactivity:Interaction.Behaviors>
    <core:EventTriggerBehavior EventName="Loaded">
        <core:EventTriggerBehavior.Actions>
            <core:InvokeCommandAction Command="{x:Bind ViewModel.LoadWheelBaseCommand}" />
        </core:EventTriggerBehavior.Actions>
    </core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>

<StackPanel Padding="16 16 16 16" Orientation="Vertical">
    <StackPanel>
        <TextBlock FontSize="18" Text="{x:Bind ViewModel.WheelBase.Name}" />
        <TextBlock FontSize="18" Text="Symptomen:" />
        <TextBlock Text="Kies hieronder een symptoom uit om te starten." />
        <ProgressRing IsActive="true"
                      Visibility="{x:Bind ViewModel.LoadWheelBaseCommand.IsRunning, Converter={StaticResource BoolToVisibilityConverter}}" />
        <TreeView ItemsSource="{x:Bind ViewModel.WheelBase.Symptoms, Mode=OneWay}">
            <TreeView.ItemTemplate>
                <DataTemplate x:DataType="wheelBase:SymptomModel">
                    <TreeViewItem ItemsSource="{x:Bind Children}" Content="{x:Bind Description}" />
                </DataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </StackPanel>
    <Button VerticalAlignment="Bottom" Command="{x:Bind ViewModel.LoadWheelBaseCommand}"
            Content="Refresh">
    </Button>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

我的视图模型:

    public class WheelBaseViewModel : ObservableRecipient
{
    public WheelBaseModel WheelBase { get; set; }

    public string WheelBaseName { get; set; }

    private readonly WheelBaseService _wheelBaseService;

    public IAsyncRelayCommand LoadWheelBaseCommand { get; }

    public WheelBaseViewModel(WheelBaseService wheelBaseService)
    {
        _wheelBaseService = wheelBaseService;
        LoadWheelBaseCommand = new AsyncRelayCommand(FetchWheelBase);
    }

    public async Task FetchWheelBase()
    {
        WheelBase = await _wheelBaseService.GetWheelBase(WheelBaseName);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的型号:

namespace ThrustmasterGuide.Model.WheelBase
{
public class WheelBaseModel : ObservableObject
{
    public string Name { get; set; }

    public ObservableCollection<SymptomModel> Symptoms { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

}

我的代码背后:

    public sealed partial class WheelBasePage : Page
{
    public WheelBasePage()
    {
        this.InitializeComponent();
        this.DataContext = App.Current.Services.GetService<WheelBaseViewModel>();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        this.ViewModel.WheelBaseName = e.Parameter as string;
    }

    public WheelBaseViewModel ViewModel => (WheelBaseViewModel)DataContext;
}
Run Code Online (Sandbox Code Playgroud)

我在将 UI 绑定到 WheelBaseModel 值时错过了什么?

更新我添加了 mode=OneWay,但仍然没有更新。

应该注意的是,我在导航后显示内容框架内的页面吗?

Kev*_*han 7

{x:Bind} 的默认模式为 OneTime,而 {Binding} 的默认模式为 OneWay。


小智 6

我相信您需要使用 SetProperty 以便知道何时引发此类事件?

https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/observableobject

namespace ThrustmasterGuide.Model.WheelBase
{
public class WheelBaseModel : ObservableObject
{
    public string Name
    {
        get => name;
        set => SetProperty(ref name, value);
    }

    public ObservableCollection<SymptomModel> Symptoms { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并且绑定模式 = OneWay

<TextBlock FontSize="18" Text="{x:Bind ViewModel.WheelBase.Name, Mode=OneWay}" /> 
Run Code Online (Sandbox Code Playgroud)