uwp 继承了 属性 数据绑定未更新 UI

uwp inherited property data binding not updating the UI

3 步嵌套字符串 属性 未更新 UI。当我更新 EvidenceName 属性 时,它不会立即反映在 UI 上,直到我返回并再次出现在该页面上,在这种情况下,视图模型将再次初始化。

我有一个包含以下代码的 xaml 页面:

<TextBlock Text="{x:Bind ViewModel.SelectedEvidence.EvidenceName, Mode=OneWay}" />

ViewModel 属性 代码隐藏:

public EvidenceViewModel ViewModel { get; } = new EvidenceViewModel();

EvidenceViewModel 中的选定证据 属性:

    public Evidence SelectedEvidence
    {
        get => _selectedEvidence;
        set => Set(ref _selectedEvidence, value); //this calls for RaisePropertyChanged
    }

EvidenceViewModel 派生自 Observable class,用于引发 属性 更改。

public class Observable : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return;
        }

        storage = value;
        OnPropertyChanged(propertyName);
    }

    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

EvidenceName 属性 在 Evidence class

    public string EvidenceName
    {
        get { return _evidenceName; }
        set 
        {
            if (_evidenceName != value)
            {
                _evidenceName = value; 
                RaisePropertyChanged();
            }
        }
    }

更新 1

如果我直接在 EvidenceViewModel 中放置一个简单的字符串 属性 并将 UI 文本块绑定到该字符串 属性,则更改会按预期实时反映。

更新 2

经过进一步的调试后,我发现 class 从父 class 继承的任何 属性 在绑定中都无法正常工作,因此 EvidenceName 属性 实际上来自父 class EvidenceBase 并被继承到子 class Evidence.

更新 3

Nswagger 为客户端生成的文件中的证据 class

EvidenceBase 代码class

EvidenceName 属性 实际存在于 EvidenceBase class

RasiePropertyChanged EvidenceBase

中的代码

您可以让 Evidence class 继承自 Observable class 并调用 EvidenceName 中的 OnPropertyChanged 方法。

例如:

public class Evidence:Observable
{
    private string _evidenceName;
    public string EvidenceName
    {
        get { return _evidenceName; }
        set
        {
            if (_evidenceName != value)
            {
                _evidenceName = value;
                OnPropertyChanged("EvidenceName");
            }
        }
    }
}

更新: 我已经测试了您的 Update 3 中的代码,我发现问题出在 Evidence class 中的覆盖。 请检查以下代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    ViewModel.SelectedEvidence.EvidenceName = "testName";
}


public abstract partial class EvidenceBase : System.ComponentModel.INotifyPropertyChanged
{        
    private string _evidenceName;
    [Newtonsoft.Json.JsonProperty("evidenceName",Required =Newtonsoft.Json.Required.Default,NullValueHandling =Newtonsoft.Json.NullValueHandling.Ignore)]
    public string EvidenceName
    {
        get { return _evidenceName; }
        set
        {
            if(_evidenceName!=value)
            {
                _evidenceName = value;
                RaisePropertyChanged("EvidenceName");
            }
        }
    }
    protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

public partial class Evidence : EvidenceBase, System.ComponentModel.INotifyPropertyChanged
{

//Remove the override of PropertyChanged property and RaisePropertyChanged method to avoid hide the ones inherited from base class.
}

public class Observable : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return;
        }

        storage = value;
        OnPropertyChanged(propertyName);
    }
    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public class EvidenceViewModel:Observable
{
    private Evidence _selectedEvidence;
    public Evidence SelectedEvidence
    {
        get { return _selectedEvidence; }
        set
        {
            Set(ref _selectedEvidence, value);
        }
    }
    public EvidenceViewModel()
    {
        _selectedEvidence = new Evidence();
    }
}

如果代码无法准确说明您关于 PropertyChanged 的​​代码,请随时与我联系。