我正在尝试将按钮的<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
事件触发的嵌套属性?什么是解决方案?
答案 0 :(得分:0)
您发布的为我工作的内容的实施是:
<Window ... xmlns:vm="clr-namespace:MyApp.ViewModels" ... >
<Window.DataContext>
<vm:ViewModelContainingMediaPlayer />
</Window.DataContext>
...
<Button Visibility="{Binding MediaPlayer.CurrentState, Converter={StaticResource TestConverter}}" ... />
...
</Window>