0
votes

I have a xml file that looks like:

tech.xml

<?xml version="1.0" encoding="utf-8" ?>
<Tech>
<item ID="1" CATEGORY="example_1" NAME="example1" MIN_LEVEL1 ="1"    MAX_LEVEL1 ="10"/>

.

.

<item ID="102" CATEGORY="example_1222" NAME="example1333" MIN_LEVEL1 ="1"    MAX_LEVEL1 ="10"/>

</Tech>

I am binding this to a DataGridTextColumn of a datagrid using an xmldataprovider

<XmlDataProvider x:Key="tech" Source="tech.xml" XPath="Tech" />

like this

<DataGrid ItemsSource="{Binding someotherclass}">

<DataGridTextColumn Binding  Source="{StaticResource tech}"   XPath="@NAME" />

.
.
.
other datagrid columns...

</DataGrid>

The problem I have is that all the rows in the DataGridTextColumn output display the value "example1"

instead of the values example1....example1333 as one would expect.

Note that the datagrid ItemsSource is bound to some other data file, only the DataGridTextColumn is bound to tech.xml.

1
Do you know that DataGrid will iterate all rows based on its ItemsSource property?stukselbax

1 Answers

1
votes

One of the possible way to do this - use the converter. But you need to have some field or property, which will connect your xml data with someotherclass data. I have created sample app which connect two collection by its index. Hope its help.

Sample app

Here the code:

MainWindow.xaml:

<Window x:Class="XmlAndSeparateSource.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:XmlAndSeparateSource"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>        
    <XmlDataProvider x:Key="TechSource" Source="tech.xml"  XPath="Tech/item" />
    <local:RowNumberConverter x:Key="rowNumberConverter" />
</Window.Resources>
<Grid>
    <DataGrid ItemsSource="{Binding }"
              AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="xml">
                <DataGridTextColumn.Binding>
                    <MultiBinding Converter="{StaticResource rowNumberConverter}">
                        <Binding Source="{StaticResource TechSource}" />
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}" />
                        <Binding />
                    </MultiBinding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>
            <DataGridTextColumn Header="string" Binding="{Binding}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>
</Window>

MainWindow.cs

namespace XmlAndSeparateSource
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        DataContext = new List<string>()
        {
            "str1",
            "str2",
            "str3",
            "str4",
        };
        InitializeComponent();

    }
}
}

RowNumberConverter.cs:

class RowNumberConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        //get the grid and the item
        IEnumerable<XmlNode> xml = values[0] as IEnumerable<XmlNode>;
        DataGrid grid = values[1] as DataGrid;
        Object item = values[2];
        int index = grid.Items.IndexOf(item);

        return xml.ElementAt(index).Attributes.GetNamedItem("NAME").Value;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

tech.xml:

<Tech>
    <item ID="1" CATEGORY="example_1" NAME="example1" MIN_LEVEL1 ="1" MAX_LEVEL1 ="10"/>
    <item ID="2" CATEGORY="example_2" NAME="example2" MIN_LEVEL1 ="1" MAX_LEVEL1 ="10"/>
    <item ID="3" CATEGORY="example_3" NAME="example3" MIN_LEVEL1 ="1" MAX_LEVEL1 ="10"/>
    <item ID="102" CATEGORY="example_1222" NAME="example1333" MIN_LEVEL1 ="1" MAX_LEVEL1 ="10"/>
</Tech>