将一个视图模型内的变量绑定到另一个视图模型内的另一个变量 [英] Binding a variable inside a viewmodel to a different variable in another viewmodel

查看:99
本文介绍了将一个视图模型内的变量绑定到另一个视图模型内的另一个变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MVVM模式实现WPF应用程序.

I'm implementing a WPF application using the MVVM pattern.

该应用程序基本上是一个通讯面板(通讯面板),其上方放置有控件(例如拨号盘,内部通讯线路等).控件小部件也已使用MVVM模式实现,因为这使我们能够轻松地逐个进行测试.

The application is basically a communications panel (comms panel) with control widgets laid on top of it (e.g., dial pads, intercom lines, etc). The control widgets have also been implemented using the MVVM pattern, as this allows us to easily test them on an individual basis.

我有这个拨号盘"控件,它在其视图模型中公开了DialedNumber公共字段:

I have this "dial pad" control widget, which exposes a DialedNumber public field in its view model:

public string DialedNumber
    {
        get { return _dialPadModel.DialedNumber; }
        set
        {
            _dialPadModel.DialedNumber = value;
            RaisePropertyChanged("DialedNumber");
        }
    }

拨号盘"控件小部件还通过视图中的公共字段公开其视图模型:

The "dial pad" control widget also exposes its view model via a public field in the view:

public DialPadViewModel DialPadViewModel
    {
        get { return DataContext as DialPadViewModel; }
    }

它还通过其视图公开它,该视图仅从视图模型的公共字段中进行写入/读取:

And it also exposes it through its view, which just writes/reads from the public field in the view model:

public string DialedNumber
    {
        get
        {
            return DialPadViewModel.DialedNumber;
        }
        set
        {
            DialPadViewModel.DialedNumber = value;
        }
    }

DialPad放在通讯面板(也使用MVVM实现)中,其视图模型中具有DialedPABXNumber公共字段:

The DialPad is placed in a comms panel (also implemented using MVVM), which has a DialedPABXNumber public field in its view model:

public string DialedPABXNumber
    {
        get { return _dialedPABXNumber; }
        set
        {
            _dialedPABXNumber = value;
            OnPropertyChanged("DialedPABXNumber");
        }
    }

现在,我希望能够将DialPad中的DialedNumber字段链接到comms面板中的DialedPABXNumber字段.但是,我正在努力提出正确的XAML语法来做到这一点.我的方法是这样的:

Now, I want to be able to link the DialedNumber field from the DialPad to the DialedPABXNumber field from the comms panel. However, I'm struggling in coming up with the right XAML syntax in order to do it. My approach would be something like this:

<PanelControls:DialPad x:Name="MyDialPad2" DialPadViewModel.DialedNumber="{Binding Path=CommsPanelViewModel.DialedPABXNumber, Mode=OneWayToSource}"/>

这样做,加载通讯面板XAML时出现运行时异常.更具体地说:

By doing this, I'm getting a runtime exception when the comms panel XAML is loaded. More specifically:

无法设置未知成员'{http://schemas.microsoft.com/winfx/2006/xaml/presentation} DialPadModel.DialedNumber'.

Cannot set unknown member '{http://schemas.microsoft.com/winfx/2006/xaml/presentation}DialPadModel.DialedNumber'.

如何在XAML中指定要访问DialPadViewModel.DialedNumber的内容?

How can I specify in the XAML that I'd like to access DialPadViewModel.DialedNumber?

添加有关组件如何组合在一起的背景信息.该应用程序的主窗口有两个子窗口:左侧的控制面板和动态加载的适当的comms面板.

Adding this background information about how the components fit together. The application's main window has two sub-windows: a control panel on the left and the proper comms panel, which is loaded dynamically.

<Window x:Class="Comms.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Views="clr-namespace:Comms.View"
    xmlns:ViewModel="clr-namespace:Comms.ViewModel"
    Title="Comms" Height="350" Width="525" Closing="WindowClosing">
<Window.Resources>
    <DataTemplate x:Name="CommsControlPanelViewModel" DataType="{x:Type ViewModel:CommsControlPanelViewModel}">
        <Views:CommsControlPanelView x:Name="CommsControlPanelView"/>
    </DataTemplate>
    <DataTemplate x:Name="CommsPanelViewModel" DataType="{x:Type ViewModel:CommsPanelViewModel}">
        <Views:CommsPanelView x:Name="CommsPanelView"/>
    </DataTemplate>
</Window.Resources>

<StackPanel x:Name="Layout" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Horizontal">
    <ContentControl Content="{Binding CommsControlPanelView}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    <ContentControl Content="{Binding CommsPanelView}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</StackPanel>

comms面板是动态加载的.这是面板的XAML文件:

The comms panel is dynamically loaded. Here's the XAML file for the panel:

<Border x:Name="CommsPanelBorder"
    Style="{DynamicResource BorderTemplate}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:PanelControls="clr-namespace:CommsPanelControlsLib.View;assembly=CommsPanelControlsLib"
    VerticalAlignment="Top">
<StackPanel>
    <!-- PABX Dial Pad -->
    <StackPanel Orientation="Horizontal">
    <PanelControls:DialPad x:Name="MyDialPad2" DialPadViewModel.DialedNumber="{Binding Path=CommsPanelViewModel.DialedPABXNumber, Mode=OneWayToSource}"/>
    </StackPanel>
</StackPanel>

推荐答案

与Blachshma长时间聊天(感谢Blachshma!)之后,我修改了DialPad代码,方法是放弃其模型并将视图模型内部的代码移至其代码后面.

After a long chat with Blachshma (thanks Blachshma!), I modified the DialPad code by getting rid of its model and moving the code inside the viewmodel to its code behind.

我在面板的XAML文件中使用的绑定如下:

The binding I've used in the panel's XAML file is as follows:

<PanelControls:DialPad x:Name="MyDialPad2" DialedNumber="{Binding Path=CommsPanelViewModel.DialedPABXNumber, Mode=OneWayToSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/>

我可以确认单击拨号盘中的按钮是否有效地触发了CommsPanelViewModel内DialedPABXNumber字段中的更改,这正是我想要的.但是,为此,我对DialPad的代码进行了一些重大修改,现在我无法对其进行单元测试.我会将问题标记为已回答,然后将打开一个新问题来处理这个新问题.

I can confirm that clicking the buttons in the dial pad is effectively triggering a change in the DialedPABXNumber field inside the CommsPanelViewModel, which is what I wanted. However, in order to do that, I made some heavy modifications in the DialPad's code and now I cannot perform unit tests on it. I'll mark the question as answered and I'll open a new one in order to deal with this new issue.

感谢大家的投入!

这篇关于将一个视图模型内的变量绑定到另一个视图模型内的另一个变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆