繁体   English   中英

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));
}

Evidence class 中的 EvidenceName 属性

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

更新 1

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

更新 2

After some further debugging I found out that any property which is being inherited by the class from parent class doesnt work well in binding, so EvidenceName property was actually coming from parent class EvidenceBase and was being inherited into child class Evidence .

更新 3

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

图 1

EvidenceBase class 的代码

图 2

EvidenceBase class 中实际存在的EvidenceName属性

图 3

EvidenceBase中的RasiePropertyChanged代码

图 5

您可以让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");
            }
        }
    }
}

更新:我已经测试了您更新 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();
    }
}

如果代码不能 state 您的关于 PropertyChanged 的代码完全正确,请随时与我联系。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM