Reputation: 51
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
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