如何将父视图中的参数设置到在用户控件中声明为静态资源的视图模型中

发布于 2024-12-13 03:14:33 字数 1377 浏览 3 评论 0原文

我有以下用于视图/视图模型的(压缩的)silverlight xaml:

<UserControl x:Class=MyView>    
    <UserControl.Resources>
        <MyViewModel x:Name="MyViewModel"/>
    </UserControl.Resources>

    <Grid DataContext="{Binding Source={StaticResource MyViewModel}}">
<UserControl>

希望大家看起来都很熟悉。

但是,我想创建同一个视图用户控件的 2 个实例,但要将参数传递给视图模型,以允许我根据传递到视图模型的属性获得略有不同的视图模型数据。像这样的事情:

<UserControl x:Class=MyView>    
    <UserControl.Resources>
        <MyViewModel x:Name="MyViewModel" Filter="Some value set at a higher level"/>
    </UserControl.Resources>

    <Grid DataContext="{Binding Source={StaticResource MyViewModel}}">
<UserControl>

问题是我无法在用户控件内对 Filter 参数进行硬编码,但需要将其设置在更高的级别。有没有办法通过绑定从上层获取过滤器参数,语法是什么样的。我希望像下面这样:

要么直接从父级,例如:

<MyView>
    <MyView.ViewModel Filter="All">
</MyView>
<MyView>
    <MyView.ViewModel Filter="Some">
</MyView>

或者从用户控件向上看,例如:

<UserControl.Resources>
    <MyViewModel x:Name="MyViewModel" Filter="{Binding FilterTypeFromDataContextHigherUpTheTree}"/>
</UserControl.Resources>

但我不知道是否可以直接从父级引用静态资源视图模型设置属性,或者语法是什么样的。

我也不知道是否有更简单的方法来做到这一点,因为我怀疑我的方法不是很优雅。

真正的问题是如何将参数传递到静态资源的视图模型中

I have the following (condensed) silverlight xaml for a view / viewmodel:

<UserControl x:Class=MyView>    
    <UserControl.Resources>
        <MyViewModel x:Name="MyViewModel"/>
    </UserControl.Resources>

    <Grid DataContext="{Binding Source={StaticResource MyViewModel}}">
<UserControl>

Hopefully this looks familiar to you all.

However, I would like to create 2 instances of this same view user control, but to pass in a parameter to the view model to allow me to have slightly different view model data based on a property which I pass into the view model. Something like:

<UserControl x:Class=MyView>    
    <UserControl.Resources>
        <MyViewModel x:Name="MyViewModel" Filter="Some value set at a higher level"/>
    </UserControl.Resources>

    <Grid DataContext="{Binding Source={StaticResource MyViewModel}}">
<UserControl>

The problem is that I can't hard code the Filter parameter inside the user control, but need to set it at a higher level. Is there a way to obtain the filter parameter from higher up via binding, and what would the syntax look like. I was hoping something like the following:

Either directly from the parent something like:

<MyView>
    <MyView.ViewModel Filter="All">
</MyView>
<MyView>
    <MyView.ViewModel Filter="Some">
</MyView>

Or from user control looking upwards, something like:

<UserControl.Resources>
    <MyViewModel x:Name="MyViewModel" Filter="{Binding FilterTypeFromDataContextHigherUpTheTree}"/>
</UserControl.Resources>

but I don't know if is is possible to directly refer to the static resource view model from the parent in order to set a property, or what the syntax would look like.

I also don't know if there is an easier way to do this, as I suspect my approach is not very elegant.

The real question is how can I pass a parameter into a view model which is a static resourd

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风吹短裙飘 2024-12-20 03:14:33

尽管可以将 ViewModel 存储为资源,但我们通常将 ViewModel 设置为视图的 DataContext。然后,如果有人需要通过视图访问 ViewModel,他们只需将 DataContext 转换为正确的 ViewModel 类型并直接访问它的属性即可。

如果您想为过滤器选择绑定路线,您有多种选择。如果子控件放置在模板(或样式)中的父控件内部,则可以将 Bnding Soure 设置为relativeSource.TemplatedParent。您还可以使用 ElementName,但前提是命名元素位于同一范围内(在上面的示例中,命名元素必须位于 MyView 内部的某个位置)。

我能想到的最后一个选项是在 MyView 上公开过滤器的 DependencyProperty,然后将 ViewModel 的绑定设置到该属性。这将有效地使过滤器冒泡,以便可以在 MyView 外部访问它,但我根本不喜欢这种方法,因为它向 View 添加属性只是为了将它们传递给 ViewModel。那绝对不应该发生。 ViewModel 应始终可独立于 View 进行访问,这就是为什么我建议通过 DataContext 属性(推断)或通过专门针对 ViewModel 的自定义属性(显式)公开它。

Though it's possible to store the ViewModel as a resource, we usually see the ViewModel set as the DataContext of a view. Then, if someone needs to access the ViewModel through the View, they just cast the DataContext to the proper ViewModel type and access it's properties directly.

If you want to go the Binding route for your Filter you have a couple of choices. You can set the Bnding Soure to RelativeSource.TemplatedParent if the child control is placed inside of the parent control in a template (or Style). You could also use ElementName, but only if the named element is inside of the same scope (in your example above, the named element would have to be somewhere inside of MyView).

The final option I can think of would be to expose a DependencyProperty for the filter on MyView and then set the binding of the ViewModel to that property. This would effectively bubble the filter so that it's accessible outside of MyView, but I don't like this approach at all because it's adding properties to the View just for the sake of passing them to the ViewModel. That should never happen. The ViewModel should always be accessible independantly of the View, which is why I recommend exposing it through the DataContext property (inferred) or through a custom property specifically for the ViewModel (explicit).

浅唱ヾ落雨殇 2024-12-20 03:14:33

我有时会使用我的 ViewModel 执行此操作(例如,将它们实例化为资源)。当我这样做时,我让我的虚拟机扩展了 DependencyObject,原因我将在稍后详细介绍。

我建议您将它们移至 app.xaml 并将它们定义为应用程序的资源,这样每个人都可以将它们作为应用程序的资源使用。此外

<UserControl
    DataContext="{StaticResource MyViewModel}" />

,您还可以将 ViewModel 的属性绑定在一起。这就是我扩展 DependencyObject 的原因。

当然,这将您限制为 MyViewModel 的单个实例,这可能适用于您的情况,也可能不适用于您的情况。如果它不起作用,我会定义一个包含共享数据的 ViewModel,然后通过静态资源绑定到它,如您的“向上看”示例所示。

I sometimes do this with my ViewModels (e.g., instantiate them as a resource). When I do this, I have my VMs extend DependencyObject, for reasons I'll detail later.

I'd recommend that you move them to app.xaml and define them as resources of the application, where they will be available to everyone as a resource of the application. That way you can

<UserControl
    DataContext="{StaticResource MyViewModel}" />

In addition, you can bind properties of your ViewModels together. That's why I extend DependencyObject.

Of course, this limits you to a single instance of MyViewModel, which may or may not work in your case. If it doesn't work, I'd define a ViewModel which contains the shared data, then bind to this via a static resource, as in your "looking upward" example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文