【问题标题】:How to set the binding of an itemscontrol to a different ViewModel?如何将 itemscontrol 的绑定设置为不同的 ViewModel?
【发布时间】:2014-08-16 16:54:05
【问题描述】:

我一直在尝试将列表绑定到我的 ItemsControl 并不断提出绑定问题,所以我来寻求帮助。

到目前为止我的代码是:

...
<ssm:RecentFilesViewModel x:Key="RecentFilesVM" />
...

<ItemsControl ItemsSource="{Binding Source={StaticResource RecentFilesVM}, Path=Files} Margin="0 4 0 0">
    <ItemsControl.Template>
        <DataTemplate>
            <telerik:RadRibbonButton Width="285">
                <TextBlock Margin="0 0 0 2" Text="{Binding Path}" />
            </telerik:RadRibbonButton>
        </DataTemplate>
    </ItemsControl.Template>
</ItemsControl>

如果我将数据上下文设置为整个窗口,我可以显示列表,但这意味着我的所有其他绑定都不起作用。这是唯一需要这个视图模型的对象,所以我想将它设置为这个 ItemsControl 的唯一对象。有人可以帮我解决这个问题吗?它慢慢让我发疯。

编辑:

我目前采用这种方式是因为没有其他对象的直接视图模型。我们试图保持尽可能解耦,因此没有窗口数据上下文。其他一切都很好。我正在使用 PRISM 和 Telerik。

通过添加绑定源,我的所有命令绑定(连接到另一个项目中的另一个类)不再起作用。有什么方法可以确保我的绑定源保持特定于我正在操作的对象?

【问题讨论】:

  • 为什么需要保持 ViewModel 与 View 解耦?
  • 我们的目标是让软件尽可能的解耦。我们制作了很多类似的应用程序,因此我们希望能够在多个地方轻松使用代码,而无需过多的返工。通过保持解耦,我们可以轻松地说“嘿,这是我们的标准外壳”并复制项目,然后将其连接到其他软件项目中的其他组件。
  • 但是当你把ViewModel和View解耦的时候,是不是就失去了MVVM模型的特点或者优势呢?如果你想解耦这部分,你会在 View 中引入 shell?
  • 那是我没有真正解释过的东西。我们有我们的主视图(我们称之为应用程序),然后我们有这个称为外壳的视图。然后将外壳注入主视图。 shell 中没有任何功能。任何具有功能的东西都与其他东西绑定:例如。命令位于另一个项目中,该项目绑定使用标记扩展(x:静态命令:appcomands.savecommand)。
  • 我开始更多地了解你的编程模型,因为这是我第一次听到这个模型。如果一切都清楚,您需要将 List 创建到 xmal 中,并且在此视图(或 xmal)中您需要将此列表与 StaticResource 绑定,不是吗?

标签: c# wpf mvvm datacontext itemscontrol


【解决方案1】:

在窗口的DataContextViewModel 内添加RecentFilesViewModel 的属性。

然后,您可以简单地这样做:

<ItemsControl ItemsSource="{Binding RecentFilesViewModel.Files}" Margin="0 4 0 0">
    <ItemsControl.Template>
        <DataTemplate>
            <telerik:RadRibbonButton Width="285">
                <TextBlock Margin="0 0 0 2" Text="{Binding Path}" />
            </telerik:RadRibbonButton>
        </DataTemplate>
    </ItemsControl.Template>
</ItemsControl>

编辑:

根据您最近的编辑,您可以尝试将 ItemsControl 包装在 Grid 中,并将其 DataContext 设置为 RecentFiles。请注意,您不必为RecentFiled 创建资源/键,只要定义了命名空间,您就可以简单地访问它。

<Grid>
    <Grid.DataContext>
        <ssm:RecentFilesViewModel/>
    </Grid.DataContext>
    <ItemsControl ItemsSource="{Binding Files} Margin="0 4 0 0">
        <ItemsControl.Template>
            <DataTemplate>
                <telerik:RadRibbonButton Width="285">
                    <TextBlock Margin="0 0 0 2" Text="{Binding Path}" />
                </telerik:RadRibbonButton>
            </DataTemplate>
        </ItemsControl.Template>
    </ItemsControl>
</Grid>

【讨论】:

  • 窗口没有直接的视图模型,它没有数据上下文。窗口中的所有其他项目都使用 x:Static 等标记扩展名进行引用。我们试图使主窗口与所有内容尽可能分离,以便以后更容易扩展。我试过 {Binding ssm:RecentFilesViewModel.Files} 但这也不起作用。 (ssm 代表RecentFilesViewModel 类所在的命名空间)
  • 视图模型的全部意义在于向视图提供数据。一旦您将 ItemsControl 的数据上下文设置为视图模型,您就已经耦合了视图模型。您不妨将它耦合到 Window 并按照预期使用视图模型。如果你真的想要解耦,你应该看看 Prism 和 Unity。从长远来看,尝试解决与视图模型的耦合问题可能会使您的应用程序更难维护,而不仅仅是按照预期使用它们。
  • 这是有道理的,但我们尽量不这样做。我没有提到我们正在合作使用 PRISM 和 Telerik。我已将上面的代码更新为目前为止我已经设法工作的代码,但我仍然遇到问题。
猜你喜欢
  • 2016-10-11
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
相关资源
最近更新 更多