简体   繁体   中英

Binding with ValueConverter not updating in UI after value change

I have this XAML

<Label
x:Name="lblStatus"
FontSize="Small"
LineBreakMode="NoWrap"
Text="{Binding ., Mode=OneWay, StringFormat='Status: {0}', Converter={views:JobStatusConverter}}" />;

I have JobViewModel binded into it.

I have used notify property change OnPropertyChanged(new PropertyChangedEventArgs(String.Empty)); in property setter but still not success. Here is my converter

public class JobStatusConverter : IMarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is JobModel model)
        {
            if (!model.IsActive)
             {
                    return "Notactive";
            }
            if (model.IsDone)
            {
                return "Closed";
             }
        return "Open";
    }
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => null;

public object ProvideValue(IServiceProvider serviceProvider) => this;


public bool Invert { get; set; }

}

Here is my model code

    public class JobViewModel : ObservableObject
    {
    private JobModel Model { get; set; }

    public bool IsActive =>
        Model?.IsActive ?? false;

    public bool IsDone =>
        Model?.IsDone ?? false;

    public void ReceiveData()
    {
        try
        {
            Model = GetJobData("JB001");
        }
        catch (Exception ex)
        {

        }
        finally
        {
            OnPropertyChanged(new PropertyChangedEventArgs(String.Empty));
        }
    }
}

after calling ReceiveData() from command, all other UI values are updated but not lblStatus value Why this is not working?

According to https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.propertychangedeventargs.-ctor?view=netframework-4.8

An Empty value or null for the propertyName parameter indicates that all of the properties have changed.

But you are not binding to any property but to the model itself. In your particular case you could bind to IsActive , change converter a bit and it should work.

Cause: the BindingContext of Label is JobViewModel ,not JobModel .So the logic in the convert will never been called.

Since you have used data-binding ,you can set the Text of Label in the JobViewModel .

Text={Binding Content}

in ViewModel

public class JobViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

    private string content;
    public string Content
    {
        get
        {
            return content;
        }

        set
        {
            if (content != value)
            {
                content = value;
                NotifyPropertyChanged();
            }
        }
    }

    private JobModel Model { get; set; }

    public bool IsActive =>
        Model?.IsActive ?? false;

    public bool IsDone =>
        Model?.IsDone ?? false;

    public JobViewModel()
    {
        if (!Model.IsActive)
        {
            Content = "Status:Notactive";
        }
        if (Model.IsDone)
        {
            Content = "Status:Closed";
        }
        Content = "Status:Open";
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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