ReactiveList不将更新传播到IValueConverter

时间:2016-03-28 20:51:40

标签: c# xaml reactiveui

我有一个由当前正在编辑记录的运营商的电子邮件地址组成的属性:

    public ReactiveList<string> Operators { get; set; }

在视图方面,我有一个ListView记录,每个记录都会显示一个图标,显示当前用户是否为编辑操作员。

<FontIcon Glyph="&#xE104;" Visibility="{Binding Operators, 
    Converter={StaticResource IsUserEditingToVisibilityConverter} }" />

我的问题是,在运算符中发生更新时,不会触发IsUserEditingToVisibilityConverter的Convert()方法。我为调试目的设置的TextBlock确实更新了:

<TextBlock Text="{Binding Operators[0]}" />

这是IsUserEditingToVisibilityConverter的代码:

// Taken from https://blogs.msdn.microsoft.com/mim/2013/03/11/tips-winrt-converter-parameter-binding/
public class IsUserEditingToVisibilityConverter : DependencyObject, IValueConverter
{
    public UserVm CurrentUser
    {
        get { return (UserVm)GetValue(CurrentUserProperty); }
        set { SetValue(CurrentUserProperty, value); }
    }

    public static readonly DependencyProperty CurrentUserProperty =
        DependencyProperty.Register("CurrentUser",
                                    typeof(UserVm),
                                    typeof(IsUserEditingToVisibilityConverter),
                                    new PropertyMetadata(null));

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (this.CurrentUser == null) return Visibility.Collapsed;
        if (this.CurrentUser.EmailAddress == null) return Visibility.Collapsed;
        var operators = value as IList<string>;
        if (operators != null && operators.Contains(this.CurrentUser.EmailAddress))
        {
            return Visibility.Visible;
        }
        return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

1 个答案:

答案 0 :(得分:0)

绑定到Text只会更新此处的Operators更改 - 就像您要执行以下操作一样:

Operators = new ReactiveList<string>{"first", "second"};

Operators声明如下(确保引发PropertyChanged):

public ReactiveList<string> Operators
{
    get { return _operators; }
    set { this.RaiseAndSetIfChanged(ref _operators, value); }
}

如果您向列表添加项目或从列表中删除项目,将不会更新。

我认为你可能在转换器中做了太多 - 这种行为在View Model中会更好。您有一个CurrentUser属性,一个Operators列表,并使用ReactiveUI的ObservableAsPropertyHelper声明属性,当CurrentUserOperators更改时,它会更新:

private readonly ObservableAsPropertyHelper<bool> _isUserEditing;

public ReactiveList<string> Operators { get; } = new ReactiveList<string>();

public UserVm CurrentUser
{
    get { return _currentUser; }
    set { this.RaiseAndSetIfChanged(ref _currentUser, value); }
}

public bool IsUserEditing => _isUserEditing.Value;

在构造函数中:

Operators.Changed.Select(_ => Unit.Default)
    .StartWith(Unit.Default)
    .Select(_ => WhenCurrentUserEditing())
    .Switch()
    .ToProperty(this, x => x.IsUserEditing, out _isUserEditing);

WhenCurrentUserEditing实施为:

private IObservable<bool> WhenCurrentUserEditing()
{
    return this.WhenAnyValue(x => x.CurrentUser.EmailAddress)
        .Select(Operators.Contains);
}