Thursday, February 17, 2022

XamDataGrid can't bind same property twice

I came across this bug when I bound the same property twice in a XamDataGrid. I see no reason I shouldn't be able to do this. Not only did the grid throw an exception, but the exception was the wrong one. I wasted a lot of time before I realized what the real problem was. Here's a simple demonstration.

Start Visual Studio and create a new C#, WPF Framework Application. Call it AnotherXamDataGridBug. Set the XAML and Code behind to this.

<Window x:Class="AnotherXamDataGridBug.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AnotherXamDataGridBug"
        xmlns:igDP="http://infragistics.com/DataPresenter"
        mc:Ignorable="d"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <igDP:XamDataGrid DataSource="{Binding Items}" GroupByAreaLocation="None">
            <igDP:XamDataGrid.FieldLayoutSettings>
                <igDP:FieldLayoutSettings AutoGenerateFields="False"/>
            </igDP:XamDataGrid.FieldLayoutSettings>
            <igDP:XamDataGrid.FieldLayouts>
                <igDP:FieldLayout>
                    <igDP:FieldLayout.Fields>
                        <igDP:TextField Label="Name 1" Name="Name"/>
                        <igDP:TextField Label="Name 2" Name="Name"/>
                    </igDP:FieldLayout.Fields>
                </igDP:FieldLayout>
            </igDP:XamDataGrid.FieldLayouts>
        </igDP:XamDataGrid>
    </Grid>
</Window>
 
--------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Windows;
 
namespace AnotherXamDataGridBug
{
    public partial class MainWindow : Window
    {
        public class cItem
        {
            public string Name { get; set; }
        }
 
        public List<cItem> Items { get; set; }
        public MainWindow()
        {
            Items = new List<cItem>() { new cItem() { Name = "BOB" }};
            try
            {
                InitializeComponent();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.InnerException.Message);
            }
        }
    }
}

Now run it and you will see an exception being thrown by the grid.


We can see perfectly well that there is a public property called Name so this exception is wrong. Firstly, I should be able to bind to the same field twice - I can bind two text boxes to a property, why can't I bind two data grid columns? Secondly, the "field" (should say property) is there so I would expect a better error message.

According to Infragistics you can get around the problem by using AlternateBinding like this.

<igDP:TextField Label="Name 1" AlternateBinding="{Binding Name}"/>
<igDP:TextField Label="Name 2" AlternateBinding="{Binding Name}"/>

Still smells like a bug.