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

.NET MAUI中ViewModel的OnPropertyChanged首次点击不更新视图问题

.NET MAUI MVVM中Picker首次点击过滤不更新视图的问题排查

问题概述

开发.NET MAUI MVVM应用时,点击过滤按钮更新ViewModel的Projects集合后,自定义Picker控件的选项首次点击不刷新,第二次点击才生效。该功能在Xamarin.Forms中正常,尝试改用ObservableCollection也未解决问题。

相关代码片段

自定义Picker的XAML绑定

<ce:CustomBindablePicker Grid.Row="12" x:Name="prj" 
                         IsEnabled="{Binding CurrentProjectTimer.Editable}" 
                         ItemsSource="{Binding Path=Projects, Mode=TwoWay}" 
                         DisplayMemberPath="PickerText" 
                         SelectedValuePath="ID" 
                         SelectedValue="{Binding Path=CurrentProjectTimer.ProjectID}" />

ViewModel中的Projects属性

private List<QtimeUniversal.BusinessEntities.Project> _Projects;
     
public List<QtimeUniversal.BusinessEntities.Project> Projects
{
    get { return _Projects; }
    set 
    { 
        _Projects = value; 
        OnPropertyChanged("Projects");
    }
}

过滤按钮的Command绑定

<ImageButton Grid.Row="0" Grid.Column="1"  x:Name="BtnFilterProjects" 
             HeightRequest="30" WidthRequest="30" 
             IsEnabled="{Binding CurrentProjectTimer.Editable}" 
             Command="{Binding SetProjectFilterCommand}" 
             HorizontalOptions="Fill" Margin="3,0,0,0"
             Source="searchblack.png">
</ImageButton>

ViewModel中的过滤命令逻辑

public RelayCommand<string> SetProjectFilterCommand { get; set; }

public void OnSetProjectFilter(object parameter)
{
    // 过滤逻辑...
    this.Projects = filteredProjects;
    // 其他逻辑...
}

可能的解决方案

1. 检查自定义Picker的实现逻辑

问题大概率出在CustomBindablePicker对ItemsSource变更的处理上:

  • 确认自定义控件是否正确监听ItemsSource的PropertyChanged事件,在集合变更时触发内部选项刷新。
  • 检查控件是否重写了ItemsSource的属性变更回调(比如OnItemsSourceChanged方法),确保更新内部选项列表并通知UI刷新。

2. 确保在UI线程更新集合

.NET MAUI要求UI相关更新必须在主线程执行,若过滤逻辑在后台线程,需切换到主线程赋值:

public void OnSetProjectFilter(object parameter)
{
    // 过滤逻辑...
    var filtered = filteredProjects;
    MainThread.BeginInvokeOnMainThread(() => 
    {
        this.Projects = filtered;
    });
    // 其他逻辑...
}

3. 修改ItemsSource的绑定模式

ItemsSource不需要TwoWay绑定,改为OneWay可避免不必要的双向同步逻辑,可能解决更新延迟:

ItemsSource="{Binding Path=Projects, Mode=OneWay}"

4. 调整ObservableCollection的使用方式

若使用ObservableCollection,尝试不直接替换整个集合,而是更新现有集合内容(部分自定义控件对集合整体替换的监听可能存在问题):

// 先将Projects改为ObservableCollection类型
private ObservableCollection<QtimeUniversal.BusinessEntities.Project> _Projects;
public ObservableCollection<QtimeUniversal.BusinessEntities.Project> Projects
{
    get { return _Projects; }
    set 
    { 
        _Projects = value; 
        OnPropertyChanged("Projects");
    }
}

// 过滤时更新集合内容
public void OnSetProjectFilter(object parameter)
{
    // 过滤逻辑...
    var filtered = filteredProjects;
    MainThread.BeginInvokeOnMainThread(() => 
    {
        Projects.Clear();
        foreach(var item in filtered)
        {
            Projects.Add(item);
        }
    });
}

5. 强制触发绑定刷新(临时测试用)

若以上方法无效,可在ViewModel赋值后,在页面后台手动强制刷新Picker绑定(仅用于验证问题,不推荐长期使用):

// 在页面代码后台监听ViewModel的PropertyChanged事件
vmProjectTimer.PropertyChanged += (s, e) => 
{
    if(e.PropertyName == "Projects")
    {
        prj.ItemsSource = vmProjectTimer.Projects;
    }
};

内容的提问来源于stack exchange,提问作者r-m85

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:26:04