C# INotifyPropertyChanged-始终为空

C# INotifyPropertyChanged-始终为空,c#,wpf,data-binding,C#,Wpf,Data Binding,我的类“船”应该不断地改变财产“ShipOnePos”的价值。此值绑定到UI元素(图像)属性之一。我喜欢根据“ShipOnePos”(当它被更改时)更新我的UI。因此,我使用接口INotifyPropertyChanged,但UI并没有更新,PropertyChanged值始终为null 你能告诉我我错过了什么,或者这个实现中有什么错误吗 类别: 名称空间DzienNaWyscigach { 公共级船舶:INotifyPropertyChanged { 公共事件属性更改事件处理程序属性更改; 私

我的类“船”应该不断地改变财产“ShipOnePos”的价值。此值绑定到UI元素(图像)属性之一。我喜欢根据“ShipOnePos”(当它被更改时)更新我的UI。因此,我使用接口INotifyPropertyChanged,但UI并没有更新,PropertyChanged值始终为null

你能告诉我我错过了什么,或者这个实现中有什么错误吗

类别:
名称空间DzienNaWyscigach
{
公共级船舶:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged([CallerMemberName]字符串propertyName=”“)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
私人互联网;
公共国际希波涅波斯酒店
{
获取{return MyShipOnePos;}
设置{MyShipOnePos=值;
NotifyPropertyChanged();
}
}
公共无效船舶管理()
{
调度程序计时器=新调度程序();
timer.Interval=TimeSpan.From毫秒(500);
timer.Tick+=定时器_Tick;
timer.Start();
}
私有无效计时器(对象发送方、事件参数)
{
ShipOnePos=ShipOnePos+10;
}
}

}
您在单击中创建的
配送
不是您将
图像
绑定到的
配送
。您可能应该创建一个
ship
作为资源,并在
事件中单击
检索现有的
ship
并开始移动。或者,您可能希望有一个具有
ship
属性的父VM

例如,你可以这样做:

<Window.Resources>
    <local:ship x:Key="myShip"/>
</Window.Resources>
....
<Image x:Name="ShipOne" 
    HorizontalAlignment="Left" Height="71" 
    Margin="31,32,0,0" VerticalAlignment="Top" Width="80" Source="Asets/ship1.png" 
    RenderTransformOrigin="0.5,0.5"
    DataContext="{StaticResource myShip}">
...
</Image>
或者,使用父VM思想:

public class ParentVM : INotifyPropertyChanged
{
    private ship _currentShip;
    public ship CurrentShip
    {
        get { return _currentShip; }
        set { _currentShip = value;  NotifyPropertyChanged(); }
    }
    // ....
}
然后你可以做:

<Window.Resources>
    <local:ParentVM x:Key="myVM"/>
</Window.Resources>
...
<Grid DataContext="{StaticResource myVM}">
   ....
   <Image DataContext="CurrentShip" ...>
       ....
   </Image>
</Grid>

当您在应用程序中调用NotifyPropertyChanged方法时,您没有将属性名称传递给该方法setter@GordonAllocman这是不必要的,因为他正在使用CallerMemberNameattribute@WasGoodDone接得好,我错过了。
<Window.Resources>
    <local:ParentVM x:Key="myVM"/>
</Window.Resources>
...
<Grid DataContext="{StaticResource myVM}">
   ....
   <Image DataContext="CurrentShip" ...>
       ....
   </Image>
</Grid>
// Note: this might be better handled with a command rather than a click handler
private void BTN_Start_Click(object sender, RoutedEventArgs e)
{
    // Note: it might be worth caching this in a field or property
    ParentVM vm = FindResource("myVM") as ParentVM;
    vm.CurrentShip = new ship();
    vm.CurrentShip.ShipsMovment();
}