使用 MVVM 将数据传递到 Silverlight 4 中的子窗口
我有一个具有主详细信息实现的数据网格,如下所示:
<data:DataGrid x:Name="dgData" Width="600" ItemsSource="{Binding Path=ItemCollection}"
HorizontalScrollBarVisibility="Hidden" CanUserSortColumns="False" RowDetailsVisibilityChanged="dgData_RowDetailsVisibilityChanged">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Item" Width="*" Binding="{Binding Item,Mode=TwoWay}"/>
<data:DataGridTextColumn Header="Company" Width="*" Binding="{Binding Company,Mode=TwoWay}"/>
</data:DataGrid.Columns>
<data:DataGrid.RowDetailsTemplate>
<DataTemplate>
<data:DataGrid x:Name="dgrdRowDetail" Width="400" AutoGenerateColumns="False" HorizontalAlignment="Center"
HorizontalScrollBarVisibility="Hidden" Grid.Row="1">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Date" Width="*" Binding="{Binding Date,Mode=TwoWay}"/>
<data:DataGridTextColumn Header="Price" Width="*" Binding="{Binding Price, Mode=TwoWay}"/>
<data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Show More Details" Click="buttonShowDetail_Click"></Button>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
</DataTemplate>
</data:DataGrid.RowDetailsTemplate>
</data:DataGrid>
我想通过单击按钮打开一个子窗口,该按钮显示有关产品的更多详细信息。
我正在使用 MVVM 模式。我的模型包含一个方法,该方法将项目名称作为输入并返回详细信息数据。
我的问题是我应该如何将 Item 传递给 ViewModel 以从 Model 获取详细信息数据?我应该在哪里打开新的子窗口?在视图或视图模型中?
I have a datagrid with master detail implementation as follows:
<data:DataGrid x:Name="dgData" Width="600" ItemsSource="{Binding Path=ItemCollection}"
HorizontalScrollBarVisibility="Hidden" CanUserSortColumns="False" RowDetailsVisibilityChanged="dgData_RowDetailsVisibilityChanged">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Item" Width="*" Binding="{Binding Item,Mode=TwoWay}"/>
<data:DataGridTextColumn Header="Company" Width="*" Binding="{Binding Company,Mode=TwoWay}"/>
</data:DataGrid.Columns>
<data:DataGrid.RowDetailsTemplate>
<DataTemplate>
<data:DataGrid x:Name="dgrdRowDetail" Width="400" AutoGenerateColumns="False" HorizontalAlignment="Center"
HorizontalScrollBarVisibility="Hidden" Grid.Row="1">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Date" Width="*" Binding="{Binding Date,Mode=TwoWay}"/>
<data:DataGridTextColumn Header="Price" Width="*" Binding="{Binding Price, Mode=TwoWay}"/>
<data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Show More Details" Click="buttonShowDetail_Click"></Button>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
</DataTemplate>
</data:DataGrid.RowDetailsTemplate>
</data:DataGrid>
I want to open a Child window in clicking the button which shows more details about the product.
I'm using MVVM pattern. My Model contains a method which takes the Item name as input and returns the Details data.
My problem is how should I pass the Item to ViewModel which will get the Details data from Model? And where should I open the new Child Window? In View or ViewModel?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从视图模型打开子窗口违反了视图和视图模型之间的分离,而模式应该是这样的。因此,您可能没有太多选择从哪里打开子窗口 - 网格所在页面的代码。 (这也违反了该模式,但是,缺乏复杂的解决方案,这就是您所能做的一切。)我使用 MVVM 模式,但我对此并不“虔诚”。当效率要求时,我会违反该模式的一些规则。
至于将项目传递给 ViewModel - 我想您可以在 ViewModel 上创建一个表示项目 id 的属性。我一直使用子窗口作为数据输入表单来更新和添加。我倾向于为它们中的每一个创建一个 ViewModel。在您的情况下,您将有一个代表项目详细信息的 ViewModel。会有某种与该项目和详细信息相关的 ID。这将是 ViewModel 上的公共属性。您可以为子窗口创建一个构造函数,该构造函数将该 ID 作为参数。然后,子窗口构造函数可以创建 ViewModel 并向其发送 ID。
像这样的 - 其中 DomainEdit 是子窗口的名称。
然后,从发生网格按钮单击的代码后面,您可以使用新的构造函数创建子窗口,传递从网格行中的项目绑定获得的 id,并且子窗口的独立视图模型将接管。
至少,这对我来说一直是有效的。
Opening the child window from a view model violates the separation between view and view model that the pattern is supposed to be all about. So, you probably don't have much choice about where you open the child window from - the code behind for the page that the grid is on. (And that violates the pattern as well, but, short of a complicated solution, it's about all you can do.) I use the MVVM pattern, but I'm not "religious" about it. I will violate some precepts of the pattern when efficiency dictates.
As far as passing the item to the ViewModel - I suppose you can create a property on the ViewModel that represents an id for the item. I've been using child windows as data entry forms for update and add. I tend to create a ViewModel for each one of them. In your case, you would have a ViewModel that represents the details of the item. There would be some sort of ID related to the item and details. That would be a public property on the ViewModel. You could create a constructor for the child window that takes that ID as a parameter. Then, the child window constructor could create the ViewModel and send it the ID.
Something like this - where DomainEdit is the name of the child window.
Then, from code behind where the button click for the grid occurs, you create the child window with the new constructor, passing the id that you get from the item binding in the grid row, and an independent view model for the child window takes over.
At least, that is what has been working for me.
中介模式(关于我们的复合应用程序的视图之间的消息服务)完成了这项工作。此外,在子窗口服务中委托创建详细视图,并通过消息服务传递所选对象。那么你就不会遇到任何模式违规。
The mediator pattern (messaging service between views regarding our composite application) does the job. Furthermore, delegate the creation of the Detail View in a Child Window service and pass the selected object via the messaging service. Then you won't get any pattern violation.