WPF Datagrid 单击行以打开新页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27322575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Datagrid single click row to open new Page
提问by Ches Scehce
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.
我在页面上的框架中有一个 WPF Datagrid。我想单击(最好单击)一行并使用存储在其中一列中的 ID 值导航到(打开)一个新页面。
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."
使用 MouseDoubleClick 有时我可以双击行来打开一个页面。但有时它会抛出:“program.exe 中发生类型为‘System.NullReferenceException’的未处理异常附加信息:未将对象引用设置为对象的实例。”
on line (see code behind below for complete method):
在线(有关完整方法,请参阅下面的代码):
string ID = ((DataRowView)PersonDataGrid.SelectedItem).Row["PersonID"].ToString();
XAML:
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?
有没有更好的方法来打开 PersonProfile 页面?有没有一种简单的方法可以通过单击一行来打开页面?
Thanks.
谢谢。
采纳答案by ELH
A better way to do it, is to define a collection of Personthat define the DataGridItemSourceand a Property of type Personthat contains the selected Item in the DataGrid:
一个更好的方法是定义一个集合,Person该集合定义了DataGridItemSource和一个Person包含所选项目的类型的属性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 SelectedPersonand Personsare defined in the code behind of this page like so :
并且SelectedPerson和Persons在此页面后面的代码中定义,如下所示:
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 INotifyPropertyChangedis used to notify the UI of any changes in the Properties.
You could use the SelectedPersonProperty or pass it to the new page, when you receive the MouseRightButtonUpevent for example in the DataGrid:
将INotifyPropertyChanged用于通知的属性进行任何更改UI。您可以使用该SelectedPerson属性或将其传递到新页面,MouseRightButtonUp例如,当您在以下位置收到事件时DataGrid:
private void PersonDataGrid_CellClicked(object sender, MouseButtonEventArgs e)
{
if (SelectedPerson == null)
return;
this.NavigationService.Navigate(new PersonProfile(SelectedPerson));
}
and you could change the PersonProfilePage to receive a Person in its Constructor.
并且您可以更改PersonProfile页面以在其构造函数中接收一个人。
回答by Clayton Harbich
The exception you are getting is because the SelectedItem is sometimes null. To make sure you are getting the value you want use the sender object and cast it to the proper type. As for a better way I would look into the MVVM pattern. It would involve binding the SelectedItem to an object. This might be a little much because you are new but it's what I recommend.
你得到的例外是因为 SelectedItem 有时为空。为了确保您获得了您想要的值,请使用 sender 对象并将其转换为正确的类型。至于更好的方法,我会研究 MVVM 模式。这将涉及将 SelectedItem 绑定到一个对象。这可能有点多,因为您是新手,但这是我推荐的。

