first of all, I'm learning so please don't take it hard on me, please. I have a DataGrid that takes data from the database and I want to add ContextMenu which takes the first column (Id) so I can use the delete action on the database. I search a little and end up by this codes:
For adding ConextMenu XML
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="delete" Click="BtnFactorDell">
<MenuItem.Icon>
<Image Width="12" Height="12" Source="img/delete.png"/>
</MenuItem.Icon>
</ContextMenu>
</DataGrid.ContextMenu>
and for chosing the first colomn which is my id i use this:
string factorselectedid;
private void FactorGrid_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
object item = FactorGrid.SelectedItem;
factorselectedid = (FactorGrid.SelectedCells[0].Column.GetCellContent(item) as TextBlock).Text;
}
Now I have 1 problem and 1 question, first about the question is what is that TextBlock at the end? because it was TexBox in the codes I found by searching and I get some errors so I randomly change it to TextBlock and it works fine! now I'm confused about what is this.
And about my problem is when I click on empty space on the DataGridview it gives me the error:
System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values. Parameter name: index'
on the line
factorselectedid = (FactorGrid.SelectedCells[0].Column.GetCellContent(item) as TextBlock).Text;
What can I do to only work if I click on the files not empty space of my Datagrid? Thank You.
CodePudding user response:
what is that TextBlock at the end?
GetCellContent(item)
returns a FrameworkElement, but a FrameworkElement doesn't have a Text
property. In your case the thing that is returned is a (derivative of) a TextBlock
which is a FrameworkElement
(TextBlock derives from FrameworkElement), but to access the Text
property you have to cast the returned FrameworkElement
to a TextBlock
first
You might well have seen examples that cast to TextBox
; those examples would work if the thing being cast was actually a TextBox
- in your case it's not a TextBox
but it is a TextBlock
(or something else that derives from TextBlock
), so a cast to TextBlock
works OK.
System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values. Parameter name: index'
You just straight attempt to access the first cell ([0]
) in SelectedCells
without really knowing if there are any selected cells at all; if there are no selected cells, you'll hit a problem
Consider instead to check if there is at least 1 cell before trying to access is:
if(FactorGrid.SelectedCells.Count > 0)
factorselectedid = (FactorGrid.SelectedCells[0].Column.GetCellContent(item) as TextBlock)?.Text;
else
e.Handled = true; //suppress the context menu from opening at all
I've also added ?
before .Text
- it will prevent a crash if the thing is ever not a TextBlock, but it will mean that factorselectedid
ends up null
. Any code that uses factorselectedid
should perhaps check it for being null first