代码之家  ›  专栏  ›  技术社区  ›  innom

maui:从代码中更改绑定字符串不会更新ui,除非重新生成字符串(mvvm)

  •  1
  • innom  · 技术社区  · 2 年前

    这是我的绳子:

    public string EmptyViewText { get; set; } = "Please input a bin id first!*";
    

    我有一个简单的命令:

    public async Task Entry(string barcode)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            EmptyViewText = "Loading data...*";
            OnPropertyChanged();
        });
    }
    

    这是被触发的。

    这是我的课:

    public partial class BinViewModel : ObservableObject
    

    绑定本身是有效的,正如我所看到的我的价值观一样。但当我更改代码中的值时,什么也不会发生。

    绑定非常简单:

    <Label Text="{Binding EmptyViewText}"  />
    

    但是,如果我禁用字符串并重新启用它(重新渲染它),它会显示新的和相应的文本。

    这里有什么问题?

    3 回复  |  直到 2 年前
        1
  •  3
  •   IV.    2 年前

    您的代码正在调用 OnPropertyChanged() 没有争论。无论该方法在哪里,其定义都可能与此类似:

    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke( this, new PropertyChangedEventArgs(propertyName));
    }
    

    本例中的呼叫者是 Entry EmptyViewText 。它将启动属性更改事件,但在错误的属性上。

    如果你用一个明确的参数来调用它,看看它是否有区别:

    public async Task Entry(string barcode)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            EmptyViewText = "Loading data...*";
            OnPropertyChanged(nameof(EmptyViewText));
        });
    }
    
        2
  •  1
  •   Jason    2 年前

    请阅读 docs .使用时 ObservableObject 你需要实现 SetProperty 在setter中,或使用 [ObservableProperty]

    public class User : ObservableObject
    {
        private string name;
    
        public string Name
        {
            get => name;
            set => SetProperty(ref name, value);
        }
    }
    
        3
  •  1
  •   Julian    2 年前

    一个干净的解决方案是改变这一点

    public partial class BinViewModel : ObservableObject
    {
        public string EmptyViewText { get; set; } = "Please input a bin id first!*";
    }
    

    到这个

    public partial class BinViewModel : ObservableObject
    {
        [ObservableProperty]
        private string emptyViewText = "Please input a bin id first!*";
    }
    

    这个

    public async Task Entry(string barcode)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            EmptyViewText = "Loading data...*";
            OnPropertyChanged();
        });
    }
    

    public async Task Entry(string barcode)
    {
        EmptyViewText = "Loading data...*";
    
        //... whatever else you need to do (asynchronously)
    }
    

    应该没有必要将属性赋值包装在对的调用中 MainThread 因为属性绑定无论如何都会在主线程上更新。