绑定到嵌套属性WPF C#

时间:2017-11-12 20:48:15

标签: c# wpf xaml binding inotifypropertychanged

我正在尝试将按钮的<Visibility>属性绑定到自定义类的布尔属性,但是我没有收到任何通知。

我的viewmodel中有以下属性:

public MediaPlayerModel MediaPlayer { get; set; }

类型编写如下:

public class MediaPlayerModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private MediaPlayerState _currentState;
    public MediaPlayerState CurrentState
    {
        get => _currentState;
        protected set
        {
            if (!Equals(value, _currentState))
            {
                _currentState = value;
                OnPropertyChanged();
            }
        }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

MediaPlayerState声明如下:

[Serializable]
public sealed class MediaPlayerState : BaseState
{
    public bool IsRunning { get; }

    //..
}

public class BaseState : IEquatable<BaseState> {..}

然后我有以下xaml代码:

<Button Content="Button" HorizontalAlignment="Left" Margin="212,337,0,0" VerticalAlignment="Top" Width="74"
        Visibility="{Binding MediaPlayer.CurrentState, Converter={converters:TestConverter}}">
</Button>

converters:TestConverter的实施方式如下:

[ValueConversion(typeof(MediaPlayerState), typeof(Visibility))]
public class TestConverter : BaseConverter, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        var running = ((MediaPlayerState)value).IsRunning;
        if (running)
        {
            return Visibility.Visible;
        }
        return Visibility.Hidden;
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

按钮的可见性永远不会改变,并且永远不会调用转换器的方法。

我确实想出了一个替代解决方案,但它似乎是对我而言并不是一个正确的解决方案,它为其他潜在的错误打开了一扇门。

我将visibility属性绑定到MediaPlayer属性本身而不是嵌套的属性:

Visibility="{Binding MediaPlayer... unchanged}

在主窗口PropertyChanged事件期间,我正在订阅MediaPlayerModel课程中的Loaded事件:

MediaPlayer.PropertyChanged += MediaPlayerOnPropertyChanged;

事件处理程序的实现方式如下:

private void MediaPlayerOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(MediaPlayer.CurrentState))
    {
        OnPropertyChanged(nameof(MediaPlayer));
    }
}

这使它工作,但它很奇怪,因为这证明事件实际上是在正确的时间被触发,但绑定似乎不起作用。

原因是什么?为什么我无法绑定到具有有效INotifyPropertyChanged事件触发的嵌套属性?什么是解决方案?

1 个答案:

答案 0 :(得分:0)

您发布的为我工作的内容的实施是:

<Window ... xmlns:vm="clr-namespace:MyApp.ViewModels" ... >
    <Window.DataContext>
        <vm:ViewModelContainingMediaPlayer />
    </Window.DataContext>
        ...
        <Button Visibility="{Binding MediaPlayer.CurrentState, Converter={StaticResource TestConverter}}" ... />
        ...
</Window>
相关问题