<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:myapp="clr-namespace:MyPlayer.Model"
mc:Ignorable="d"
x:Class="MyPlayer.VolumeButtons"
x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480">
<UserControl.Resources>
<myapp:MusicPlayerModel x:Key="Model"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" DataContext="{StaticResource Model}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35px"/>
<ColumnDefinition Width="1.0*"/>
</Grid.ColumnDefinitions>
<Slider Value="{Binding Volume}" Margin="0,0,0,0" Grid.Column="1" VerticalAlignment="Center" x:Name="volumeSlider"/>
<Button Margin="4,4,4,4" Content="Button" x:Name="muteButton" Click="MuteButton_Click"/>
</Grid>
</UserControl>
现在问题是,当我移动滑块时数据绑定工作正常(当我移动滑块时模型会更新)。
但是,当单击一个按钮时,我会更改模型中的值并希望它更新视图。
以下代码:
private void MuteButton_Click(object sender, RoutedEventArgs e)
{
musicPlayerModel.Volume = 0;
}
模型中的代码:
public double Volume
{
get { return this.volume; }
set
{
this.volume = value;
this.OnPropertyChanged("SomeTestText");
this.OnPropertyChanged("Volume");
}
}
但是在OnPropertyChanged中,事件为空,因此没有任何反应。为什么事件为空,而不是我的滑块移动时以及如何解决它?
答案 0 :(得分:2)
您不应直接致电该活动。你正在做的是正确的,但只有正确实现OnPropertyChanged方法。在Microsoft推荐并在整个BCL中使用的模式中,OnPropertyChanged(和任何OnXXXXEventName)应如下所示:
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
// get handler (usually a local event variable or just the event)
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, e);
}
}
如果这是正确的,您不必担心该事件为空等。但您的代码显示this.OnPropertyChanged("SomeTestText");
这是不合法的。该字符串不是有效参数。根据事件模式,OnPropertyChanged事件应如上所示,这意味着您应该按如下方式调用它:
this.OnPropertyChanged(new PropertyChangedEventArgs("Volume"));
注意:如果处理程序(事件)为null,则调用应用程序尚未注册到该事件。通过代码,可以使用somevar.PropertyChanged += handlerMethod
完成此操作。
在评论中,您建议“应该”自动进行。但是在上面的代码中,您使用字符串调用OnPropertyChanged
。如前所述,这不是合法代码,因为OnXXX方法应该有一个继承自EventArgs
的参数。虽然我在你的案例中认为是一个正常的PropertyChanged事件,但是XAML和WPF为另一种解释提供了空间(对不起,现在只能达到这个目的)。
你(和我)对一件事情都错了。这个quote from MSDN解释了:
“请注意,有一个相同的 用a命名的OnPropertyChanged方法 不同的签名(参数 type是PropertyChangedEventArgs) 可以出现在很多课程上。 OnPropertyChanged用于 数据对象通知,是其中的一部分 的合同 INotifyPropertyChanged的“。
在覆盖Volume属性的代码中需要执行的操作,应该改为调用PropertyChangedCallback
,或者使用带有DependencyPropertyChangedEventArgs结构参数的OnXXX代码。如果您问我,即使您不使用原始的WPF方法,您当前的方法也会更容易; - )