My first post here! And new to coding!...
I have a WPF Datagrid in a Frame on a Page. I would like to click (preferably single click) on a row and use the ID value stored in one of the columns to Navigate to (open) a new Page.
Using MouseDoubleClick sometimes I can double click row to open a Page. But sometimes it is throwing: "An unhandled exception of type 'System.NullReferenceException' occurred in program.exe Additional information: Object reference not set to an instance of an object."
on line (see code behind below for complete method):
string ID = ((DataRowView)PersonDataGrid.SelectedItem).Row["PersonID"].ToString();
XAML:
<DataGrid x:Name="PersonDataGrid" AutoGenerateColumns="False"
SelectionMode="Single" SelectionUnit ="FullRow"
MouseDoubleClick="PersonDataGrid_CellClicked" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=PersonID}"
ClipboardContentBinding="{x:Null}" Header="ID" />
</DataGrid.Columns>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell" BasedOn="{StaticResource myDataGridCellStyle}">
<EventSetter Event="DataGridCell.MouseLeftButtonDown" Handler="PersonDataGrid_CellClicked"/>
</Style>
</DataGrid.CellStyle>
</DataGrid>
Code Behind:
private void PersonDataGrid_CellClicked(object sender, MouseButtonEventArgs e)
{
string ID = ((DataRowView)PersonDataGrid.SelectedItem).Row["PersonID"].ToString();
SelectedPersonID = Int32.Parse(ID);
this.NavigationService.Navigate(new PersonProfile());
}
Is there a better way to open the PersonProfile Page? Is there an easy way to open the Page using single click on a row?
Thanks.
A better way to do it, is to define a collection of Person
that define the DataGrid
ItemSource
and a Property of type Person
that contains the selected Item in the DataGrid
:
<DataGrid x:Name="PersonDataGrid" AutoGenerateColumns="False"
SelectionMode="Single" SelectionUnit ="FullRow"
MouseRightButtonUp="PersonDataGrid_CellClicked"
ItemsSource="{Binding Persons}"
SelectedItem="{Binding SelectedPerson}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=PersonId}" Header="Id" />
<DataGridTextColumn Binding="{Binding Path=PersonName}" Header="Name" />
</DataGrid.Columns>
</DataGrid>
and the SelectedPerson
and Persons
are defined in the code behind of this page like so :
public partial class Page1 : Page,INotifyPropertyChanged
{
private ObservableCollection<Person> _persons ;
public ObservableCollection<Person> Persons
{
get
{
return _persons;
}
set
{
if (_persons == value)
{
return;
}
_persons = value;
OnPropertyChanged();
}
}
private Person _selectedPerson ;
public Person SelectedPerson
{
get
{
return _selectedPerson;
}
set
{
if (_selectedPerson == value)
{
return;
}
_selectedPerson = value;
OnPropertyChanged();
}
}
public Page1()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Person
{
public int PersonId { get; set; }
public string PersonName { get; set; }
}
the INotifyPropertyChanged
is used to notify the UI of any changes in the Properties.
You could use the SelectedPerson
Property or pass it to the new page, when you receive the MouseRightButtonUp
event for example in the DataGrid
:
private void PersonDataGrid_CellClicked(object sender, MouseButtonEventArgs e)
{
if (SelectedPerson == null)
return;
this.NavigationService.Navigate(new PersonProfile(SelectedPerson));
}
and you could change the PersonProfile
Page to receive a Person in its Constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With