重新显示ViewModel时,DataGrid不显示SelectedItem的焦点

时间:2013-12-06 13:53:34

标签: wpf data-binding mvvm datagrid focus

PersonsViewModel有一个对应的DataTemplate,其DataGrid绑定到PersonListDataGrid.SelectedItem具有与SelectedPerson的双向数据绑定,因此当我在视图中选择一行时,PersonList中的相应项目将分配给SelectedPerson

除了一个问题之外它工作得很好:当我将屏幕切换到PersonDetailScreen,然后回来时,选择焦点就会丢失!我的意思是,SelectedPerson仍然包含其以前的值,但DataGrid在视觉上未被选中。

我做了一个测试,在viewmodel中创建了一个双向数据绑定“SelectedIndex”。然后,我可以看到实际选择在它返回时仍然存在于viewmodel中,问题似乎是:

“加载ViewModel的datatemplate时如何关注SelectedIndex的{​​{1}},并且此类viewmodel中的某些”SelectedIndex“数据绑定属性已包含值?”

3 个答案:

答案 0 :(得分:1)

如果您有TwoWay Binding,则可以从视图模型中设置DataGrid.SelectedItem值。我对你的设置有点困惑......当你说'当我切换屏幕......然后回来时,选择焦点丢失',听起来有点像你保持视图模型的存活,但不是视图?我更习惯每次都显示一个新的视图,但修复方式都是相同的。

现在,如果这是我的一个视图,我会将数据加载到构造函数的任何集合中,并(在基类内部)设置CurrentItem属性,该属性是绑定到{{1}的数据}属性到集合中的第一个项目。您应该这样做,除了不将其设置为第一个项目,而是将其设置为上次选择的任何项目。

所以答案就是每次显示视图时设置ListBox.SelectedItem属性。但是,如果您说SelectedItem属性已设置为应选择的项目,则可能需要先将其设置为任何其他值,然后将其设置回正确的项目。

答案 1 :(得分:0)

我们在这里谈论的是什么,项目选择或项目焦点?

如果你希望一个可视项目在渲染模板时获得焦点,你最好的办法是在你的xaml代码中手动设置焦点,比如,将一个处理程序挂钩到你的页面的'Loaded'事件并设置通过调用'Focus()'方法手动将焦点集中到数据网格。

我知道这会破坏一些MVVM规则,但焦点管理高度依赖于页面的可视化树,因此无法通过视图模型正确建模,视图模型应尽可能独立于视图。

答案 2 :(得分:0)

感谢Sheridan的见解,我比我想象的更容易解决问题,而且有点无意。

我在DataTemplate中直接定义了DataGrid。当模板加载时,我相信,虽然我完全不确定,将“SelectedItem”或“SelectedItem”值传递给View所需的一些初始化步骤是“丢失”。

我打算在后面的代码中手动重新选择,所以我做的是将datagrid移动到我从头创建的一些UserControl。但是,事实上,DataTemplate现在实例化了一个适当的View(从UserControl派生),而内部本身又包含datagrid,似乎“让更多的通知工作”,所以说,View会显示所选的行,就像它一样永远都应该。

所以,现在我在DataTemplate中有这个:

<DataTemplate x:Name="PersonScreenTemplate" DataType="{x:Type vm:PersonScreenViewModel}">   
    <vw:PersonScreenViewView/>
</DataTemplate>

这似乎是ViewModel-first的完美纯WPF设计模式:一个datatemplate,其内容是单个usercontrol,它反过来声明并绑定和处理所有内容。