I have a WPF DataGrid which is bound to some nodes in my XML file.
<Settings xmlns="">
<Profiles xmlns="" ActiveProfile="1">
<Profile Id="0" Desc="- none -" Port="0" Baud="0" DataBits="0" Parity="0" StopBits="0" CharDelay="0" ReadTimeout="0" ProcInterval="0" SetInterval="0" DecInterval="0" ChartInterval="0" SaveInterval="0">
<PIDs>
<PID Address="1" SetPoint="one" ProcVal="one" />
<PID Address="2" SetPoint="two" ProcVal="two" />
<PID Address="3" SetPoint="three" ProcVal="three" />
</PIDs>
</Profile>
<Profile Id="1" Desc="Test Profile 1" Port="1" Baud="19200" DataBits="7" Parity="0" StopBits="3" CharDelay="1" ReadTimeout="100" ProcInterval="100" SetInterval="0" DecInterval="0" ChartInterval="0" SaveInterval="0">
<PIDs>
<PID Address="4" SetPoint="four" ProcVal="four" />
<PID Address="5" SetPoint="five" ProcVal="five" />
<PID Address="6" SetPoint="six" ProcVal="six" />
</PIDs>
</Profile>
Here is some pertinent XAML:
<XmlDataProvider x:Name="MySettings" x:Key="MySettings" Source="Settings.xml" XPath="Settings" IsAsynchronous="False" IsInitialLoadEnabled="True"/>
<XmlDataProvider x:Name="PIDData" x:Key="PIDData" Source ="Settings.xml" XPath="Settings/Profiles"/>
<ComboBox Name="cboProfile" Width="150" Padding="10,3,4,3" ItemsSource="{Binding Source={StaticResource MySettings}, XPath=Profiles/Profile}"
SelectedValuePath="@Id" DisplayMemberPath="@Desc"
SelectedValue="{Binding Mode=TwoWay, Source={StaticResource MySettings}, XPath=Profiles/@ActiveProfile}"/>
<DataGrid Name="dgPIDData" AutoGenerateColumns="False" Height="201" HorizontalAlignment="Left" Margin="233,137,0,0" VerticalAlignment="Top" Width="444"
DataContext="{Binding Source={StaticResource PIDData}}" ItemsSource="{Binding XPath=Profile[@Id\=../@ActiveProfile]/PIDs/PID}">
<DataGrid.Columns>
<DataGridTextColumn Header="Address" Binding="{Binding XPath=@Address}"/>
<DataGridTextColumn Header="Set Point" Binding="{Binding XPath=@SetPoint}"/>
<DataGridTextColumn Header="Proc Val" Binding="{Binding XPath=@ProcVal}"/>
</DataGrid.Columns>
</DataGrid>
Here is some code-behind:
Private settingsDoc As XmlDocument
Private dp As XmlDataProvider
Private Sub MainWindow_Initialized(sender As Object, e As System.EventArgs) Handles Me.Initialized
dp = Me.TryFindResource("MySettings")
If dp IsNot Nothing Then
settingsDoc = dp.Document
settingsText = settingsDoc.OuterXml
End If
End Sub
Private Sub cboProfile_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboProfile.SelectionChanged
If Me.dgPIDData IsNot Nothing Then
If dp IsNot Nothing Then
Stop
End If
End If
End Sub
When I run the application, it properly shows items 4, 5 and 6 in the DataGrid. This is because the ItemsSource XPath reads the "ActiveProfile" value from the Profiles node, and uses that to select the proper Profile node. Even in design mode, the DataGrid shows these values.
At run-time, I change the ComboBox from the second item (index 1) to the first item (index 0). The code stops in the SelectionChanged event, so I can poll the "ActiveProfile" value, which changes from "1" to "0" properly, since the ComboBox's binding mode is TwoWay. Unfortunately, the DataGrid does not re-display with items 1, 2 and 3 like it should.
My MainWindow_Closing event has code to save the XML file if it has changed. If I do this, then the next time the application runs, the DataGrid values start at 1, 2 and 3. So the binding is working, and selecting the proper list of items from the XML file, but the DataGrid is just not updating until the next time it loads.
I thought that XmlDataProvider would automatically notify the DataGrid to refresh. I tried doing a DataGrid.Items.Refresh() in the SelectedIndexChanged event, but no luck.
Does anybody have any idea why my DataGrid won't refresh from the XML? Thanks...