Piotr
Piotr

Reputation: 51

INotifyPropertyChanged - always null

My class "ship" should change value of property "ShipOnePos" continuously. This value is binded to one of UI element (image) property. I like to update my UI according to "ShipOnePos" (when it is changed). So for this reason I use interface INotifyPropertyChanged, but UI is not updating, and PropertyChanged value is always null.

Can You advice what I miss, or what is wrong in this implementation ?

Class:

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 Binding

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

Code behind

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

Upvotes: 1

Views: 211

Answers (1)

Matt Burland
Matt Burland

Reputation: 45155

The ship you are creating in your click isn't the ship you bound your Image to. You should probably create a ship as a resource and in your Click event retrieve that existing ship and start it moving. Or else, you might want to have a parent VM with a ship property.

So for example, you could do something like this:

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

And then in your click handler:

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

Or alternatively, using the parent VM idea:

public class ParentVM : INotifyPropertyChanged
{
    private ship _currentShip;
    public ship CurrentShip
    {
        get { return _currentShip; }
        set { _currentShip = value;  NotifyPropertyChanged(); }
    }
    // ....
}

And then you could do:

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

And:

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

Upvotes: 1

Related Questions