I have been struggling with this for a while now. I have a Master / Details layout in my application, and am faced, like many others, with the problem of the DataGrid loosing its selection when disabling it. Essencialy, after selecting an element from the list to populate a series of fields, the user presses “Edit”, wich disables the DataGrid and enables all of the form’s fields. Pressing the “Save” button will revert these actions after saving the data… Pretty strait forward.
I am on Windows 7 developping with VS 2010 in the .Net Framework 4.
What I have tried:
1) Based on this post, I have tried to use the DataGrid in the June 2009 version of the WPF Toolkit, but I had the same reaction.
2) Based on this WPF CodePlex bug report, I have tried to create a custom control based on the DataGrid and to override the OnIsEnabledChanged call to remove the call to “UnselectAllCells”, but with no code example, I can’t even get it to fire once. I have tried:
public class FormMainDataGrid : DataGrid
{
static FormMainDataGrid()
{
IsEnabledProperty.OverrideMetadata(typeof(FormMainDataGrid), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIsEnabledChanged)));
}
public FormMainDataGrid() : base() { }
private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(CanUserAddRowsProperty);
d.CoerceValue(CanUserDeleteRowsProperty);
//this was added in new version !!!
/*
if (!(bool)(e.NewValue))
{
((DataGrid)d).UnselectAllCells();
}
*/
// Many commands use IsEnabled to determine if they are enabled or not
CommandManager.InvalidateRequerySuggested();
}
}
but this still unselects the currently selected row as soon as I disable the DataGrid. I have tried to interprete the last comments (in the Codeplex bug report) like this:
public class FormMainDataGrid : DataGrid
{
static FormMainDataGrid()
{
}
public static void OverrideStuff()
{
IsEnabledProperty.OverrideMetadata(typeof(FormMainDataGrid), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnIsEnabledChanged)));
}
public FormMainDataGrid() : base() { }
private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(CanUserAddRowsProperty);
d.CoerceValue(CanUserDeleteRowsProperty);
//this was added in new version !!!
/*
if (!(bool)(e.NewValue))
{
((DataGrid)d).UnselectAllCells();
}
*/
// Many commands use IsEnabled to determine if they are enabled or not
CommandManager.InvalidateRequerySuggested();
}
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
FormMainDataGrid.OverrideStuff();
base.OnStartup(e);
}
}
but that does not even fire the modified version of the method.
First, am-I going the right way for this? Considering that the Deselection is caused by this method, can I completely replace the internal call to ‘OnIsEnabledChanged’ for my own method?
Is there another way I could be tackling this problem?
Or more specificly, how can i stop the call to the base version of this method since it is not an override, thus I cannot ‘not’ call the base.OnIsEnabledChanged?
Thanks alot!
The same problem with the Up-Down key still exists with IsHitTestVisible = false.
So what I ended up doing is re-working the custom control like this:
This works pretty well… I just have to be carefull because changing the SelectedValue when the control is disable will then put it off track…
So in conclusion, I believe that your solution is the most complete, but mine allows me to keep my form’s code as lean & mean as possible.
Thanks for your help!