INotifyPropertyChanged - 始终为null

时间:2016-03-24 14:40:00

标签: c# wpf data-binding

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

你能告诉我错过了什么,或者这个实施中有什么问题?

类别:

namespace DzienNaWyscigach
{
    public class ship : INotifyPropertyChanged 
    {
        
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }

        }

        private int MyShipOnePos;

        public int ShipOnePos
        {
            get { return MyShipOnePos; }
            set { MyShipOnePos = value; 
                  NotifyPropertyChanged(); 
                }
        }

        public void ShipsMovment()
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(500);
            timer.Tick += Timer_Tick;
            timer.Start();
            
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            ShipOnePos= ShipOnePos+10;

        }
    }
}

UI绑定

<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">
            <Image.DataContext>
                <local:ship/>
            </Image.DataContext>
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform X="{Binding Path=ShipOnePos, Mode=OneWay}"/>
                </TransformGroup>
            </Image.RenderTransform>

背后的代码

 private void BTN_Start_Click(object sender, RoutedEventArgs e)
        {
           ship Ships = new ship();
            Ships.ShipsMovment();
            
        }

1 个答案:

答案 0 :(得分:1)

您在点击中创建的ship不是您ship绑定的Image。您应该创建ship作为资源,并在Click事件中检索现有的ship并开始移动。否则,您可能希望拥有ship属性的父虚拟机。

例如,您可以这样做:

<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>

然后在你的点击处理程序中:

private void BTN_Start_Click(object sender, RoutedEventArgs e)
{
    // Note: it might be worth caching this in a field or property
    ship Ships = FindResource("myShip") as ship;
    Ships.ShipsMovment();
}

或者,使用父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>

// 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();
}