TwoWay Binding fired incorrectly when using a CellSelector

I have an sfDataGrid that needs to show a mix of two different classes. Both classes have a "Name" property. For one class this is read only and for the other it's read write:-

namespace TestCellCellSelector

{

public interface IName { string Name { get; } }

public class ReadOnlyName : IName

{

public string Name { get { return "Read Only Name"; } }

}

public class ReadWriteName : IName

{

public string Name { get; set; }

}

}


I have bound an observable collection to the data grid and I'm using a cell selector to return a readonly text box with a one way binding if the class is read only and a non-readonly text box two way binding with a two way binding where the class is read write. This is correctly returning the appropriate data templates and works fine for the read write class. However, when I click in the read only text box, I get an error "A TwoWay or OneWayToSource binding cannot work on the read-only property 'Name' of type 'TestCellCellSelector.ReadOnlyName'."


Any idea how I stop this firing?


Here's the xaml:-

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:sf="http://schemas.syncfusion.com/wpf"

xmlns:local="clr-namespace:TestCellCellSelector"

mc:Ignorable="d"

Title="MainWindow" Height="450" Width="800">

IsReadOnly="True"

sf:FocusManagerHelper.FocusedElement="True"

sf:VisualContainer.WantsMouseInput="True" />

IsReadOnly="False"

sf:FocusManagerHelper.FocusedElement="True"

sf:VisualContainer.WantsMouseInput="True" />

ItemsSource="{Binding Names}"

AllowResizingColumns="True" ColumnSizer="Auto"

ShowRowHeader="True" SelectionMode="Multiple"

AllowEditing="True" EditTrigger="OnTap"

AllowDeleting="True" SelectionUnit="Row"

Grid.Column="0" Margin="2,2,2,2">

CellTemplateSelector="{StaticResource NameGridCellTemplateSelector}"

sf:FocusManagerHelper.WantsKeyInput="True" >

...and the code behind...

namespace TestCellCellSelector

{

///

/// Interaction logic for MainWindow.xaml

///

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

DataContext = new MainWindowViewModel();

}

}


public class MainWindowViewModel

{

public MainWindowViewModel()

{

Names = new ObservableCollection()

{

new ReadOnlyName(),

new ReadWriteName()

};

}


public ObservableCollection Names { get; set; }

}


public class NameGridCellTemplateSelector : DataTemplateSelector

{

public override DataTemplate SelectTemplate(object item, DependencyObject container)

{

Window window = Application.Current.MainWindow;

DataTemplate control = null;

if (item is ReadWriteName)

control = window.Resources["CellTemplateNameReadWriteTextBox"] as DataTemplate;

else

control = window.Resources["CellTemplateNameReadOnlyTextBox"] as DataTemplate;

return control;

}

}

}



NB. I picked a text box as a simple example of this but I'm actually using the cell selector to return a variety of controls including comboboxes, datepickers etc so I need a solution that will accomodate any edit control.


1 Reply 1 reply marked as answer

DH Declan Hillier July 31, 2023 09:37 AM UTC

Never mind. I managed to solve it.

The problem was that I had the mapping name set on the template column and also had the text property bound on text box template returned by the template selector. Remove the mapping name from the template column fixed the problem.

I guess what was happening was that the mouse click was hitting the column's edit cell before being passed to the contained textbox and that was firing the two way binding of the cell. The binding on the textbox behaves fine.


Marked as answer
Loader.
Up arrow icon