I have a WPF Window which has its DataContext set to a ViewModel object, and which has child controls databound to properties of that DataContext (ViewModel) object. Those databound controls are correctly displaying the data from the ViewModel object. However, there is a StatusBar containing a TextBlock, which is supposed to update when the underlying ViewModel object's bound property changes -- and TextBlock is not updating.
The problem is due to the fact that nothing is attaching to the ViewModel object's PropertyChanged event during the binding (or when it is set as the DataContext), and so notification of changes to the data are not routed to the TextBlock control.
The abbreviated XAML is this:
Window x:Class="MarketFeedViewer.MainWindow"
xmlns:marketFeedViewer="clr-namespace:MarketFeedViewer"
mc:Ignorable="d"
Title="Market Data Viewer" Height="500" Width="300" >
<Window.DataContext>
<marketFeedViewer:MarketDataViewModel />
</Window.DataContext>
<Grid Margin="0,0,0,0">
<WrapPanel HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="0" Grid.ColumnSpan="2" Margin="0,3,3,0">
<Label>Host</Label>
<TextBox x:Name="Host" VerticalContentAlignment="Center" MinWidth="100" Text="{Binding Host}" />
<Label Content="Port" />
<TextBox x:Name="Port" MinWidth="50" VerticalContentAlignment="Center" Text="{Binding Port}"/>
</WrapPanel>
<DataGrid x:Name="PricesGrid" HorizontalAlignment="Center" Margin="5,5,5,5" Grid.Row="1" Grid.ColumnSpan="2"
Grid.Column="0"
VerticalAlignment="Stretch"
ItemsSource="{Binding MarketData}"
MinHeight="200" MinWidth="200" VerticalScrollBarVisibility="Auto"/>
<StatusBar Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="0">
<StatusBarItem HorizontalAlignment="Right">
<TextBlock Name="StatusText" Text="{Binding FeedStatus}" />
</StatusBarItem>
</StatusBar>
</Grid>
</Window>
The ViewModel class implements INotifyPropertyChanged, and when the Status Bar's underlying property is updated from a background thread, it is firing the PropertyChange event:
public class MarketDataViewModel : INotifyPropertyChanged
{
public ObservableCollection<WPFL1Data> MarketData { get; set; }
...
public string FeedStatus
{
get { return GetStatus(); }
}
...
...
private void ClientOnOnStateChange(object sender, MarketFeedConnectionState e)
{
if (App.IsInvokeRequired)
{
App.InvokeMethod(() => ClientOnOnStateChange(sender, e));
return;
}
...
// here is where Status Bar's TextBlock should be notified
// that value has changed.
OnPropertyChanged(FeedStatus);
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
// problem is here: handler == null
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
What is the missing piece of code of XAML configuration?