You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让OnPropertyChanged在用户切换设备方向时触发?

设备方向变化时未触发更新的解决方案

你的核心问题是仅在ViewModel构造函数中获取了一次设备方向,没有订阅方向变化的监听事件,所以用户切换设备方向时,Orientation属性不会自动更新。

解决步骤

  1. 订阅DeviceDisplay.Current.MainDisplayInfoChanged事件,监听设备显示信息(包括方向)的变化
  2. 在事件回调中重新计算并更新Orientation属性
  3. 实现IDisposable接口,在ViewModel销毁时取消事件订阅,避免内存泄漏

修改后的TabletPodcastViewModel.cs代码

namespace NerdNewsNavigator2.ViewModel.Tablet;

public partial class TabletPodcastViewModel : ObservableObject, IDisposable
{
    #region Properties
    readonly TwitService _twitService;
    [ObservableProperty]
    int _orientation;
    public ObservableCollection<Podcast> Podcasts { get; set; } = new();
    #endregion

    public TabletPodcastViewModel(TwitService twit)
    {
        _twitService = twit;
        _ = GetPodcasts();
        // 初始化方向值
        Orientation = OnDeviceOrientationChange();
        System.Diagnostics.Debug.WriteLine("Device orientation is: " + Orientation);
        // 订阅方向变化事件
        DeviceDisplay.Current.MainDisplayInfoChanged += OnDisplayInfoChanged;
    }

    #region Get the Podcast and set the Podcast List
    async Task GetPodcasts()
    {
        var podcastList = await TwitService.GetListOfPodcasts();
        foreach (var item in podcastList)
        {
            var temp = await Task.FromResult(FeedService.GetFeed(item));
            Podcasts.Add(temp);
        }
    }
    #endregion

    public int OnDeviceOrientationChange()
    {
        return DeviceDisplay.Current.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? 2 : 3;
    }

    // 设备显示信息变化的回调方法
    private void OnDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
    {
        Orientation = OnDeviceOrientationChange();
        System.Diagnostics.Debug.WriteLine("Device orientation updated to: " + Orientation);
    }

    [RelayCommand]
    async Task Tap(string url)
    {
        var encodedUrl = HttpUtility.UrlEncode(url);
        await Shell.Current.GoToAsync($"{nameof(TabletShowPage)}?Url={encodedUrl}");
    }

    // 实现IDisposable,取消事件订阅
    public void Dispose()
    {
        DeviceDisplay.Current.MainDisplayInfoChanged -= OnDisplayInfoChanged;
        GC.SuppressFinalize(this);
    }
}

关键说明

  • 事件订阅:通过MainDisplayInfoChanged事件,设备方向变化时会自动触发OnDisplayInfoChanged方法,此时重新计算并赋值Orientation,由于使用了[ObservableProperty],属性变更会自动通知UI更新(无需手动调用OnPropertyChanged)。
  • 内存泄漏防护:ViewModel实现IDisposable后,在页面销毁时(比如MAUI中页面出栈时),需要调用Dispose方法取消事件订阅,防止ViewModel被事件引用无法回收。你可以在TabletPodcastPage的OnDisappearing方法中补充:
protected override void OnDisappearing()
{
    base.OnDisappearing();
    if (BindingContext is IDisposable disposable)
    {
        disposable.Dispose();
    }
}
  • 初始值优化:构造函数中直接赋值Orientation = ...即可,[ObservableProperty]会自动触发属性变更通知,不需要额外调用OnPropertyChanged(nameof(Orientation))。

内容的提问来源于stack exchange,提问作者James Crutchley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:40:22