Reputation: 47
I'm having this code where I would like to update the image in my main window when the property in a usercontrol changes. But somehow I can't get the trigger working.
Some of the XAML code
<StatusBar MinHeight="10" MaxHeight="20" VerticalAlignment="Bottom" Grid.Row="2">
<Image x:Name="SomeNameHere">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=pingable}" Value="false">
<Setter Property="Image.Source" Value="Icons/MainWindow/StatusOffline_stop_32x.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=pingable}" Value="true">
<Setter Property="Image.Source" Value="Icons/MainWindow/StatusOK_32x.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StatusBar>
The part where the property comes from
public bool pingable { get; set; }
public MainWindow()
{
InitializeComponent();
pingable = PingHost("some random IP");
}
public bool PingHost(string nameOrAddress)
{
pingable = false;
Ping pinger = new Ping();
try
{
PingReply reply = pinger.Send(nameOrAddress);
pingable = reply.Status == IPStatus.Success;
}
catch (PingException)
{
// Discard PingExceptions and return false;
}
return pingable;
}
I see the property during debugging in the XAML editor so it seemingly gets recognized and I also see the value would fit. But somehow the setter doesn't get executed. Someone an idea on this?
Thanks and have a nice day!
Upvotes: 0
Views: 1734
Reputation: 2119
While the other two answers before mine point out that INotifyPropertyChanged
needs to be implemented -- and that is somewhat important for a normal WPF application -- I don't believe that actually matters here. Your ping request looks synchronous, so the UI isn't actually going to be loaded by the time you update your value, making INotifyPropertyChanged
irrelevant.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Thread.Sleep(2000); // pretending to ping
Flag = true;
}
public bool Flag { get; set; }
}
XAML:
<Grid>
<CheckBox IsChecked="{Binding Flag}" />
</Grid>
This is checked when the window eventually loads. If this were asynchronous, it would be a different story.
I see the property during debugging in the XAML editor
I'm not sure what this means. I suspect the actual problem here is that you don't have a DataContext defined. (Maybe it is, but I can't see it here!)
You've created the property on the window itself, so... what if you switched your trigger to be...
<DataTrigger Binding="{Binding Path=pingable, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" Value="false">
Upvotes: 0
Reputation: 401
If you RaisePropertyChanged on the getter and setter, it will notify the XAML when the property changes and make the triggers fire. Try this code:
bool _pingable;
public bool pingable
{
get{return _pingable;}
set{ _pingable = value; RaisePropertyChanged;}
};
Upvotes: 0
Reputation: 35270
You need to raise your PropertyChanged
event on pingable
to get the view to update.
Basically, in order to get the view to know that it needs to update some control based on a binding, your view model needs to implement INotifyPropertyChanged
; any time you want the update the view based on a change in the view model, you need to raise PropertyChanged
from the view model and pass it the name of the bound property whose value was updated.
Upvotes: 1