C# 反应列表不向IValueConverter传播更新

C# 反应列表不向IValueConverter传播更新,c#,xaml,reactiveui,C#,Xaml,Reactiveui,我有一个由当前编辑记录的操作员的电子邮件地址组成的属性: public ReactiveList<string> Operators { get; set; } 公共反应列表运算符{get;set;} 在视图端,我有一个记录列表视图,每个记录都有一个图标显示当前用户是否是编辑操作员 <FontIcon Glyph="&#xE104;" Visibility="{Binding Operators, Converter={StaticResource

我有一个由当前编辑记录的操作员的电子邮件地址组成的属性:

    public ReactiveList<string> Operators { get; set; }
公共反应列表运算符{get;set;}
在视图端,我有一个记录列表视图,每个记录都有一个图标显示当前用户是否是编辑操作员

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

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

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

以下是ISUserEditingToviabilityConverter的代码:

// 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();
    }
}
//取自https://blogs.msdn.microsoft.com/mim/2013/03/11/tips-winrt-converter-parameter-binding/
公共类是UserEditingToviabilityConverter:DependencyObject,IValueConverter
{
公共用户VM当前用户
{
获取{return(UserVm)GetValue(CurrentUserProperty);}
set{SetValue(CurrentUserProperty,value);}
}
公共静态只读DependencyProperty CurrentUserProperty=
DependencyProperty.Register(“当前用户”,
类型(UserVm),
类型(IsUserEditingToviabilityConverter),
新属性元数据(空);
公共对象转换(对象值、类型targetType、对象参数、字符串语言)
{
if(this.CurrentUser==null)返回Visibility.Collapsed;
if(this.CurrentUser.EmailAddress==null)返回Visibility.Collapsed;
var运算符=作为IList的值;
if(operators!=null&&operators.Contains(this.CurrentUser.EmailAddress))
{
返回可见性。可见;
}
返回可见性。折叠;
}
公共对象转换回(对象值、类型targetType、对象参数、字符串语言)
{
抛出新的NotImplementedException();
}
}

文本的绑定只会在此处更新
操作符
更改-就像您要执行以下操作一样:

Operators = new ReactiveList<string>{"first", "second"};
如果向列表中添加项目或从列表中删除项目,则不会更新

我认为您可能在转换器中做得太多了-在视图模型中这种行为会更好。您将拥有一个
CurrentUser
属性、一个
操作符
列表,并使用ReactiveUI的
ObservablesPropertyHelper
声明属性,该属性将在
CurrentUser
操作符
更改时更新:

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;
当当前用户编辑时,
实现为:

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

我以为反应列表会触发添加/删除的项目。。。另外,我知道如果我在我的子视图模型中有关于操作符的信息,您的解决方案会很好,但事实并非如此。
Operators.Changed.Select(_ => Unit.Default)
    .StartWith(Unit.Default)
    .Select(_ => WhenCurrentUserEditing())
    .Switch()
    .ToProperty(this, x => x.IsUserEditing, out _isUserEditing);
private IObservable<bool> WhenCurrentUserEditing()
{
    return this.WhenAnyValue(x => x.CurrentUser.EmailAddress)
        .Select(Operators.Contains);
}