Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Datagrid single click row to open new Page

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.

like image 635
Ches Scehce Avatar asked Dec 05 '14 18:12

Ches Scehce


1 Answers

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.

like image 86
SamTh3D3v Avatar answered Oct 21 '22 20:10

SamTh3D3v