Search code examples
c#.netwpfselectionchanged

WPF: Raise programmatically a SelectionChangedEvent with an object


MouseDoubleClick opens a new window in which I update the DataTable by changing the content of TextBoxes. After updating a DataTable, I need to raise a SelectionChangedEvent in order to update strings to the correct values (SelectionChangedEvent triggers when you select a row in the DataGrid). That would be simple enough, if I wasn't programmatically selecting the same row after refreshing the DataGrid, which means that the selection technically never changes and the values won't update unless I select another row.

I solved the issue by changing the index to -1 then changing it back to the previous value, but I would rather just call the handler directly DG_Part_SelectionChanged();. Refactoring the logic into a new function doesn't work.

    public void DG_Part_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        if (CurrentPartID != 0)
        {
            int lastId = CurrentPartID;
            EditWindow ew = new EditWindow(CurrentPartID)
            {
                Owner = this
            };
            ew.ShowDialog();
            if (Global.invokeDataGridParts == "yes")
            {
                // Refreshes the datagrid with an updated datatable
                InvokeDataGridPart();
                // Finds and selects the new index position of the modified row
                SqlPartsSetToRow(lastId);
                // Scrolls into view
                dg_part.ScrollToCenterOfView(dg_part.Items[dg_part.SelectedIndex]);
                // Highlights the row
                Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() =>
                {
                    DataGridRow row = (DataGridRow)dg_part.ItemContainerGenerator.ContainerFromIndex(dg_part.SelectedIndex);
                    row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }
                ));
                // Restores index so that you may re-select the previous selection correctly
                int saveIndex = dg_part.SelectedIndex;
                dg_part.SelectedIndex = -1;
                dg_part.SelectedIndex = saveIndex;
            }
        }
    }

   public void DG_Part_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        DataGrid gd = (DataGrid)sender;
        if (gd.SelectedItem is DataRowView row_selected)
        {
            Global.del = row_selected["DEL"].ToString();
            Global.delez = row_selected["DELEZ"].ToString();
            Global.cr_tu = row_selected["CRTU"].ToString();
            Global.st_clanov = row_selected["ST"].ToString();
            Global.lastnik = row_selected["LASTNIK"].ToString();
            Global.naslov = row_selected["NASLOV"].ToString();
            Global.ps = row_selected["PS"].ToString();
            Global.obmocje2 = row_selected["OBMOCJE"].ToString();
            Global.drzava = row_selected["DRZAVA"].ToString();
            Global.emso = row_selected["EMSO"].ToString();
            Global.maticna_st = row_selected["MATICNA"].ToString();
            Global.reference = row_selected["REFERENCE"].ToString();
            Global.opis = row_selected["OPIS"].ToString();
            Global.opomba = row_selected["OPOMBA"].ToString();
        }
    }

Solution

  • Had to change DataGrid gd = (DataGrid)sender; into DataGrid gd = (DataGrid)dg_part; and refactor the logic:

        public void DG_Part_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            DG_Part_Selection();
        }
    
        public void DG_Part_Selection()
        {
            DataGrid gd = (DataGrid)dg_part;
            if (gd.SelectedItem is DataRowView row_selected)
            {
                Global.del = row_selected["DEL"].ToString();
                Global.delez = row_selected["DELEZ"].ToString();
                Global.cr_tu = row_selected["CRTU"].ToString();
                Global.st_clanov = row_selected["ST"].ToString();
                Global.lastnik = row_selected["LASTNIK"].ToString();
                Global.naslov = row_selected["NASLOV"].ToString();
                Global.ps = row_selected["PS"].ToString();
                Global.obmocje2 = row_selected["OBMOCJE"].ToString();
                Global.drzava = row_selected["DRZAVA"].ToString();
                Global.emso = row_selected["EMSO"].ToString();
                Global.maticna_st = row_selected["MATICNA"].ToString();
                Global.reference = row_selected["REFERENCE"].ToString();
                Global.opis = row_selected["OPIS"].ToString();
                Global.opomba = row_selected["OPOMBA"].ToString();
            }
        }
    

    Then simply call the handler:

        public void DG_Part_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (CurrentPartID != 0)
            {
                int lastId = CurrentPartID;
                EditWindow ew = new EditWindow(CurrentPartID)
                {
                    Owner = this
                };
                ew.ShowDialog();
                if (Global.invokeDataGridParts == "yes")
                {
                    // Refreshes the datagrid with an updated datatable
                    InvokeDataGridPart();
                    // Finds and selects the new index position of the modified row
                    SqlPartsSetToRow(lastId);
                    // Scrolls into view
                    dg_part.ScrollToCenterOfView(dg_part.Items[dg_part.SelectedIndex]);
                    // Highlights the row
                    Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() =>
                    {
                        DataGridRow row = (DataGridRow)dg_part.ItemContainerGenerator.ContainerFromIndex(dg_part.SelectedIndex);
                        row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                    }
                    ));
                    // Restores index so that you may re-select the previous selection correctly
                    DG_Part_Selection();
                }
            }
        }