aierda 2023-10-12 18:02 采纳率: 72.1%
浏览 82
已结题

如何给一个UserControl绑定特定的ViewModel

问题描述:
WPF项目,使用的是prism框架。首先有一个主界面,其它的界面都设计为UserControl,
主界面通过导航的方式去加载UserControl, 大致代码如下

<Window x:Class="BookDispenser.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:prism="http://prismlibrary.com/" 
        xmlns:usercontrols="clr-namespace:MyProject.Controls" 
        prism:ViewModelLocator.AutoWireViewModel="True" //这里自动绑定相同名字的ViewModel
        mc:Ignorable="d"
        Title="Project"
        Height="450" Width="800">
    <Grid>
        ...
        ....
        <!--这里显示UserControl-->
        <ScrollViewer>
            <ContentControl  prism:RegionManager.RegionName="ContentRegion" />
        </ScrollViewer>

    </Grid>
</Window>
  每个UserControl都有一个相同名称的VewModel,自动绑定,一一对应。

这个本来没有问题。但是目前情况不一样了,两个UserControl对应一个
ViewModel,其中一个UserControl是给正常人看的,一个是UserControl是
给残疾人看的,内容一样,但是界面排版和 样式不一样,数据绑定也一样,
所以需要绑定同一个ViewModel

目前残疾人的UserControl的名称比较长,加了前缀,所以无法自动绑定
到ViewModel,所以需要额外指定。

我曾尝试在UserControl.cs后台去绑定,但是呢,不行,代码如下

using BookDispenser.ViewModels;
using System.Windows.Controls;

namespace BookDispenser.Views
{
    /// <summary>
    /// AccessibilityTakeReservedProcessingView.xaml 的交互逻辑
    /// </summary>
    public partial class AccessibilityTakeReservedProcessingView : UserControl
    {
        public AccessibilityTakeReservedProcessingView()
        {
            InitializeComponent();
            /*
             * 我本想在后台进行绑定,但是行不通,会报错。
             * 因为TakeReservedProcessingViewModel继承NavigableViewModel,所以它的构造函数带参数
             * 我尝试在TakeReservedProcessingViewModel中加上无参数的构造函数,但又不允许;
             * 但是带参数的话,又会报错,所以最终这种方式还是行不通
             */
            this.DataContext = new TakeReservedProcessingViewModel(null,null,null,null);
        }
    }
}

提出问题:对于我的这种情况,有什么方法可以解决问题呢?
期待各位能人的指点,感谢!

  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2023-10-12 18:03
    关注

    引自强大而免费的微信小程序:皆我百晓生。如有帮助,还望采纳。


    对于这种情况,可以使用Prism框架提供的RegionContext来解决。

    首先,在主界面的XAML中,给残疾人UserControl添加一个RegionContext,并设置其内容为ViewModel的实例,代码如下:

    <ScrollViewer>
        <ContentControl prism:RegionManager.RegionName="ContentRegion">
            <prism:RegionContext.RegionContext>
                <prism:RegionContext>
                    <prism:RegionContext.DataContext>
                        <viewmodels:TakeReservedProcessingViewModel />
                    </prism:RegionContext.DataContext>
                </prism:RegionContext>
            </prism:RegionContext.RegionContext>
        </ContentControl>
    </ScrollViewer>
    

    然后,在正常人UserControl的XAML中,使用RegionManager.Regions属性获取到ContentRegion的Region,并将Binding.Value属性绑定到RegionContext的内容,代码如下:

    <UserControl>
        <UserControl.DataContext>
            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}"
                     Path="(prism:RegionManager.Regions)[ContentRegion].Context.DataContext" />
        </UserControl.DataContext>
    </UserControl>
    

    这样做的原理是,通过RegionContext将ViewModel的实例传递给ContentControl的Region,然后在另一个UserControl中使用Binding将ViewModel的实例绑定到DataContext上。

    需要注意的是,需要在XAML的头部引用prism命名空间:

    xmlns:prism="http://prismlibrary.com/"
    

    并且也要在UserControl的类文件中引用相应的ViewModel:

    using MyProject.ViewModels;
    

    这样就可以实现对一个ViewModel的绑定了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 10月21日
  • 已采纳回答 10月13日
  • 创建了问题 10月12日