2011-05-30 42 views
0

我正在寻找一种合适的方式将控件绑定在一起。 假设我有两个单独的视图。每个视图都有一个控件,我想将它们绑定在一起。第一个控件有一个依赖属性,并且期望第二个控件将被分配给该属性。
如果我正确理解MVVM的想法,我不希望在我的viewmodel中有这些控件,只是数据。所以我试图找到一种合适的方式将控件从一个视图传递给另一个视图。
视图的代码中的依赖属性绑定控件?这是否是正确的方式来做到这一点?虽然看起来不太干净。考虑到视图的数据上下文将是viewmodel而不是后面的代码,我将被迫将这些控件绑定在代码中而不是声明式的方式。
也许我在这里错过了一些简单的东西。任何建议表示赞赏。 将一个控件绑定到第二个控件的属性时,它们被放置在不同视图中


澄清:
情况如下:2个不同的意见和2个不同的控制。每个控件都驻留在单独的视图中。 ControlA具有ControlB类型的依赖项属性。所以我需要做一些类似于元素绑定的东西,但问题是我没有同一视图中的两个元素。

+0

你告诉我什么是你的目标/任务?不是技术细节。所以我可以帮助你更好:) – msfanboy 2011-05-31 08:23:18

回答

0

我不是很确定你的意思是“绑定在一起”,但也许你正在寻找这样的东西?

<local:UserControlB x:Name="UserControlB" /> 
<local:UserControlA local:UserControlA.SubControlB="{Binding ElementName=UserControlB}" /> 

为什么你要在视图之间传递控件?通常你传递数据或DataContext

+0

谢谢你的建议,但它只会在控件处于相同视图时才起作用。我真的不想像你说的那样通过控制,但我没有看到另一种方式来做到这一点。我使用第三方控件,并通过设计controlA取决于controlB。在我的情况下,他们被分开看法。 – incognito 2011-05-31 07:30:57

+0

@incognito你可以在ControlA的加载事件中做一些事情,以便在可视化树中查找两个控件的父元素,然后沿着它走下去寻找ControlB。 – Rachel 2011-05-31 12:12:52

0

你的意思是你有两个视图,每个视图都有一个UserControlFoo,并且你希望那两个UserControlFoo实例链接到相同的数据?就像两个视图上的滑块绑定到相同的数据,并且当一个滑块移动另一个滑块以反映更改?

如果是这样的话,只要绑定两个视图相同的视图模型实例,请确保募集OnPropertyChanged当值的变化,并设置绑定UpdateSourceTriggerPropertyChanged

这里是具有两个(或更多)使用相同的视图模型与滑块视图作为DataContext一个例子:

在视图模型:

private double _sliderValue; 
public double SliderValue 
{ 
    get { return _sliderValue; } 

    set 
    { 
     if (_sliderValue != value) 
     { 
      _sliderValue = value; 

      OnPropertyChanged("SliderValue"); 
     } 
    } 
} 

在查看:

<Slider Value="{Binding Path=SliderValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

然后只是与DataContext具有相同的ViewModel用于两个视图

这是否回答你的问题?

如果你不熟悉OnPropertyChanged,看看约什 - 史密斯的文章:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

+0

我想我没有解释得很好。情况如下:2种不同的观点和2种不同的控制。每个控件都驻留在单独的视图中。 ControlA具有ControlB类型的依赖项属性。所以我需要做一些类似于元素绑定的东西,但问题是我没有同一视图中的两个元素。 – incognito 2011-05-31 09:09:22

+0

好的,所以你实际上在一个控件上有一个依赖属性是另一个控件。我不知道有一种方法可以做到这一点,没有一些脏肮脏的代码,ViewModel知道他们的Views等等,对不起。 – 2011-05-31 10:35:08

0

通常,您将使用mediator pattern使视图内通信,而不是通过一个依赖项属性。这使您可以彼此独立地开发视图和控件,因为调解器将提供视图之间的松散耦合。

假设您有2个视图,其中包含控件A的视图A和包含控件B的视图B.您还可以为每个视图创建视图模型。视图模型是视图之间的通信将通过使用共享中介发生。或者,您可以将中介添加到每个控件作为依赖项属性,并将该属性绑定到视图模型的中介。

视图A

  • 包含对照A
  • 具有其的DataContext设置为视图模型甲
  • 与控制用户的交互获取/设置查看使用数据绑定
  • 查看模型模型属性包含一个共享参考调解员/信使

查看B

  • 包含对照B
  • 具有其的DataContext设置为视图模型乙使用数据绑定
  • 查看模型包含一个共享参照介体/信使
  • 与对照B用户交互获取/设置查看模型属性

因此,当用户与视图A上​​的控件A进行交互时,交互会导致中介发布包含有关事件信息的消息。视图B的视图模型订阅在发布此消息时被通知,并更新其属性,这通过数据绑定触发控件B的更改。

两个视图模型使用的介体都是相同的实例,通常使用IoC容器注入到视图模型中。实现一个中介是相当平凡的,并且还有一些MVVM工具包,如MVVM Light提供了一个'Messenger'类来支持这种通信。

关键的想法是您的视图和控件不再有任何对方的知识,而是交互抽象为消息的发布和订阅;促进不同对象和对象类型之间的松耦合通信。

中保和MVVM资源:

  1. Simple Mediator
  2. MVVM Light Toolkit
  3. Implementing the MVVM Pattern
  4. Event Aggregation
+1

我注意到你的评论“我使用第三方控件,通过设计控制A取决于控件B.在我的情况下,它们被放在不同的视图中”。鉴于您没有完全控制您正在使用的控件,您可能不得不放弃使用MVVM模式,并将视图的知识泄漏到视图模型中。我能想到的唯一另一种选择是编写描述控件的抽象概念,并在视图模型中使用它。你能链接到提供你的控件的供应商吗? – Oppositional 2011-06-02 00:23:28

+0

谢谢你的详细解答,甚至更好的评论。我最终将控件A引入Viewmodel A(我不想在开始时这样做),然后将该控件A传递给ViewModel B的构造函数。这种方法解决了这个问题,但会导致一些副作用。我非常喜欢关于抽象的想法。由于有更多的控制取决于控制A,我想我会尝试一下。 – incognito 2011-06-02 19:17:29

+0

你看到了什么副作用?我认为一个问题可能是一个问题,即用户控件通常是DependencyObjects,并且具有线程关联性,使得在后台线程上执行工作变得更加困难。 – Oppositional 2011-06-02 23:12:06

相关问题