I have a DataGrid that I am creating and populating from code. When the grid first shows up the RadioButton column, “Include”, seems to work just fine. The problem is that after I change the sort the RadioButton no longer works correctly. You can spam click on it, click out of the window and then come back in, or maybe event just wait, it will eventually work, but obviously it isn’t really usable. Here is an simple example:
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
InitializeDataGrid();
}
private void InitializeDataGrid()
{
var table = GetTestTable();
var newGrid = new DataGrid
{
CanUserAddRows = false,
CanUserSortColumns = true,
AutoGenerateColumns = true,
ItemsSource = table.AsDataView(),
DataContext = table
};
newGrid.AutoGeneratingColumn += dataGrid_AutoGeneratingColumn;
UxRootGrid.Children.Add(newGrid);
}
private static DataTable GetTestTable()
{
DataTable table = new DataTable("name");
table.Columns.Add("Include", typeof (bool));
table.Columns.Add("Number", typeof (int));
for (int i = 0; i < 5; i++)
{
var row = table.NewRow();
row[0] = false;
row[1] = i;
table.Rows.Add(row);
}
return table;
}
void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName != "Include")
{
return;
}
DataTemplate template = GetDataTemplate();
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn
{
Header = "Include",
CellTemplate = template,
CellEditingTemplate = template,
};
e.Column = templateColumn;
}
private static DataTemplate GetDataTemplate()
{
var elementFactory = new FrameworkElementFactory(typeof (RadioButton));
var binding = new Binding("Include")
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
elementFactory.SetBinding(ToggleButton.IsCheckedProperty, binding);
elementFactory.SetValue(RadioButton.GroupNameProperty, "BindingGroup");
return new DataTemplate {VisualTree = elementFactory};
}
}
}
Here is the Xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Name="UxRootGrid">
</StackPanel>
</Window>
So, to see the problem:
1. Start the application
2. Click on the RadioButton next to the Number 1.
3. Click on the “Number” header twice (to sort in descending order).
4. Now click on the RadioButton next to the Number 4.
5. Notice that the RadioButton next to the Number 1 is now deselected, but that the RadioButton next to the Number 4 is not selected.
6. Click on the RadioButton next to the Number 4 a few more times. Eventually it will become selected.
UPDATE: I had another of my coworkers try this on his machine, and it took him a time or 2 more of sorting / selecting radio buttons to see the issue happen, but eventually he ended up in the same position as me.
I’m pretty new to WPF, so I’m hoping this is just a simple mistake on my part. Any help in getting a workaround or another method of setting this up would be greatly appreciated.
I was able to solve the problem by using the RadioButtonExtended class by Peter Staev, located here: http://pstaev.blogspot.com/2008/10/binding-ischecked-property-of.html
As he suggests in his post, I just replaced the usages of RadioButton with RadioButtonExtended and then did my binding to IsCheckedReal rather than IsChecked.