2

I am working on a WPF project, and right now I am validating data in a DataGrid. so, when invalid data is inserted I show a notification image in the RowHeader. Everything goes well so far.

But my question is: Is there a way to block any other control in the apllication when "Invalid" data is inserted excepting the current row of the DataGrid?? Or, what can I do to prevent the current row from lose the focus until correct data is entered??

So far my idea is to Raise an event using eventAggregator to inform all the controls about the error. But this is hard since I would have to suscribe a method in each control I could have.

Hope someone can help me, thank you in advance.

Dante
  • 3,208
  • 9
  • 38
  • 56

1 Answers1

1

by canceling the CellEditEnding Event you stop the cell from losing focus:

public MainWindow()
{
    InitializeComponent();

    dataGrid1.ItemsSource = new List<TestClass>() { new TestClass() };
    dataGrid1.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(dataGrid1_CellEditEnding);
}

void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    if(whateveryouwant == true)
        return;
     else    
    e.Cancel = true;
}

EDIT:

EventAggregator is a good way to solve it, but since you know that but seem to not like it, a simpler way would be following, though you would have to specify a few types of controls that should be able to be stopped:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        dataGrid1.ItemsSource = new List<TestClass>() { new TestClass() };
        dataGrid1.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(dataGrid1_CellEditEnding);

        MouseDownHandler = new MouseButtonEventHandler((sender, args) => { args.Handled = true; });
        MouseClickHandler = new RoutedEventHandler((sender, args) => { args.Handled = true; });
    }

    private bool IsMouseEventStopped = false;
    private RoutedEventHandler MouseClickHandler = null;
    private MouseButtonEventHandler MouseDownHandler = null;

    void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        bool correctCellValue = false;

        //correctCellValue = true to stop editing, if the cell value is correct


        if (correctCellValue)
        {
            // unblock mouse events
            if (IsMouseEventStopped == true)
            {
                foreach (Button c in FindVisualChildren<Button>(this))
                    c.Click -= MouseClickHandler;
                foreach (TextBox c in FindVisualChildren<TextBox>(this))
                    c.PreviewMouseLeftButtonDown -= MouseDownHandler;
            }
            IsMouseEventStopped = false;
        }
        else
        {
            e.Cancel = true;
            // block mouse events to certain controls
            if (IsMouseEventStopped == false)
            {
                IsMouseEventStopped = true;
                foreach (Button c in FindVisualChildren<Button>(this))
                    c.Click += MouseClickHandler;
                foreach (TextBox c in FindVisualChildren<TextBox>(this))
                    c.PreviewMouseLeftButtonDown += MouseDownHandler;
            }
        }
    }

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                    yield return (T)child;

                foreach (T childOfChild in FindVisualChildren<T>(child))
                    yield return childOfChild;
            }
        }
    }
}

thanks to Bryce Kahle for the FindVisualChildren from here

Community
  • 1
  • 1
cppanda
  • 1,235
  • 1
  • 15
  • 29
  • Yes, I have tried this, but I need my whole application to get unresponsive excepting my current row while it has any error – Dante Jul 11 '12 at 14:52
  • 2
    @Dante This approach seems like a good idea at first, but it ends up being pretty user hostile very quickly. Users get really confused and frustrated when the application forces them to fill in THIS DATA RIGHT HERE RIGHT NOW. Different people will have different flows and may want to insert data in a slightly different order. A lot of times, I've noticed that people will put in dummy data with the intent of fixing it a few seconds later. You may want to consider a design where they can't click an "Accept" button until the data is right, but can still use other controls. – Pete Baughman Jul 11 '12 at 17:50
  • 1
    +1 to Pete Baughman, i just added it as possible answer, but i don't quite like it also. a better ui design pattern would be to revert the cell value if the cell looses focus while the value is incorrect. or you could highlight the cell red until a correct value is entered. – cppanda Jul 11 '12 at 17:53