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



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

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

我做了一个测试,在视图模型中创建了一个双向数据绑定的"SelectedIndex"。然后,当它回来时,我可以看到实际的选择仍然存在于视图模型中,问题似乎是:

"当ViewModel的数据模板已加载,并且该视图模型中的某些"SelectedIndex"数据绑定属性已包含值时,如何聚焦ItemsControlSelectedIndex?"

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

现在,如果这是我的一个视图,我会从构造函数将数据加载到任何集合中,并(在基类内部)将绑定到ListBox.SelectedItem属性的CurrentItem属性设置为集合中的第一个项。你也应该这样做,只是你不把它设置为第一个项目,而是把它设置成最后一个选择的项目。

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

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

如果你想让可视化项目在渲染模板时获得焦点,最好的办法是在xaml的代码后面手动设置焦点,比如,将处理程序挂接到页面的"Loaded"事件,并通过调用其"focus()"方法将焦点手动设置到数据网格。

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

多亏了Sheridan的真知灼见,我比想象中更容易地解决了这个问题,而且有点无意。

我在DataTemplate中直接定义了DataGrid。当加载模板时,我相信,尽管我根本不确定,但将"SelectedItem"或"SelectedItem"值传递给视图所需的一些初始化步骤"丢失"了。

我计划在代码背后手动进行重新选择,所以我所做的是将数据网格移动到我从头创建的一些UserControl中。但是,DataTemplate现在在其内部实例化了一个适当的视图(从UserControl派生而来),而该视图又包含数据网格,这一事实似乎"让更多的通知发挥作用",也就是说,视图会像往常一样显示所选行。

所以,现在我在我的数据模板中有了这个:

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

这似乎是ViewModel的完美纯WPF设计模式:一个数据模板,其内容是一个单一的用户控件,然后声明、绑定和处理所有内容。

相关内容

  • 没有找到相关文章

最新更新