<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 中,该事件为空,因此什么也没有发生。为什么事件为空,而不是当我的滑块移动时事件为空?如何解决?

有帮助吗?

解决方案

您不应该直接调用该事件。您所做的事情是正确的,但前提是 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"));

笔记:如果处理程序(事件)为空,则调用应用程序尚未注册到该事件。通过代码,这可以完成 somevar.PropertyChanged += handlerMethod.


编辑:关于 Slider/WPF 和事件

在评论中,您建议它“应该”自动进行。但在上面的代码中,你调用 OnPropertyChanged 用一根绳子。如前所述,这不是合法的代码,因为 OnXXX 方法应该有一个参数,该参数继承自 EventArgs. 。尽管我在您的案例中考虑了正常的 PropertyChanged 事件,但 XAML 和 WPF 为另一种解释提供了空间(抱歉现在才讨论这一点)。

你(和我)在一件事上犯了错误。这 引用自MSDN 解释说:

“请注意,有一个相同命名的onPropertychanged方法,具有不同的签名(参数类型为propertyChangeDeventargs),可以出现在许多类上。该变成的变成用于数据对象通知,并且是InotifyPropertyChanged合同的一部分。”

您需要在覆盖 Volume 属性的代码中执行什么操作,您应该调用 PropertyChangedCallback 相反,或者使用您的 OnXXX 代码作为参数 a DependencyPropertyChangedEventArgs 结构。如果您问我,即使您不使用原始的 WPF 方法,您当前的方法也要容易得多;-)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top