简体   繁体   English

将IsEnabled绑定到父ViewModel而不是UserControl ViewModel

[英]Binding IsEnabled to the parent ViewModel instead of the UserControl ViewModel

I developed a user control in SilverLight that contains several child controls. 我在SilverLight中开发了一个包含多个子控件的用户控件。 Textboxes , ComboBoxes and so on. TextboxesComboBoxes等。

The problem is, when I include that UserControl into a parent view and set the complete control to IsEnabled=False , the child controls in that specific UserControl are still enabled. 问题是,当我将UserControl包含到父视图中并将完整控件设置为IsEnabled=False ,仍然启用该特定UserControl中的子控件。

After all I found the problem. 毕竟我发现了问题。

Adding something like that, implies that the IsEnabled Binding is located in the UserControl binding, not as expected from myself in the DataContext of the parent. 添加类似的东西意味着IsEnabled Binding位于UserControl绑定中,而不是我自己在父级的DataContext中所期望的。

<localControls:TeamEmployeeSelector Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
          IsEnabled="{Binding CanModify}" DataContext="{Binding Confidentiality}"/>

QUESTION: 题:
But there's still the question how I can bind the IsEnabled to the ViewModel of the Parent? 但是仍然存在如何将IsEnabled绑定到Parent的ViewModel的问题? Because it's not very elegant to copy the CanModify Property to the ViewModel of the Child Control. 因为将CanModify属性复制到Child Control的ViewModel并不是很优雅。

Instead of modifying a binding in some way (for example you can make it dependent on other control name as it is proposed in other answer) I would move separate the control which will be disabled and control where DataContext will be changed. 而不是以某种方式修改绑定(例如,你可以使它依赖于其他答案中提出的其他控件名称)我将单独移动将被禁用的控件并控制DataContext将被更改的位置。 For example: 例如:

<ContentControl IsEnabled="{Binding CanModify}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
    <localControls:TeamEmployeeSelector DataContext="{Binding Confidentiality}"/>
</ContentControl>

Here is how I would do this. 我就是这样做的。

Your TeamEmployeeSelector UserControl will contain a single root level element which by default is a Grid and is given the name "LayoutRoot". 您的TeamEmployeeSelector UserControl将包含单个根级别元素,默认情况下,该元素是Grid并且名称为“LayoutRoot”。

Now you can bind the IsEnabled property of all the child elements to the UserControl like this:- 现在,您可以将所有子元素的IsEnabled属性绑定到UserControl如下所示: -

 <TextBox IsEnabled="{Binding Parent.IsEnabled, ElementName=LayoutRoot}" ... />

By using element-to-element binding you do not need to copy the CanModify property in to child view models. 通过使用元素到元素绑定,您无需将CanModify属性复制到子视图模型中。

Some might suggest that you simply add an x:Name to your UserControl element and then bind directly to it rather than going via the Parent property of the root element as I do above. 有些人可能会建议您只需将一个x:Name添加到UserControl元素,然后直接绑定到它,而不是像我上面那样通过根元素的Parent属性。 That'll work ok in Silverlight 4 but not in 3 or WP7. 这在Silverlight 4中可以正常工作,但在3或WP7中没有。 Personally I prefer the above. 我个人比较喜欢以上。

I don't know if it's possible in Silverlight, but in WPF I would use RelativeSource. 我不知道它是否可以在Silverlight中使用,但在WPF中我会使用RelativeSource。

Have a look here . 看看这里

Hope this help ! 希望这有帮助!

<localControls:TeamEmployeeSelector Grid.Row="1" Grid.Column="0"
Grid.ColumnSpan="2" IsEnabled="{Binding ElementName=SomeElementName_With_Parent_ViewModel, Path=DataContext.CanModify}" DataContext="{Binding Confidentiality}"/>

This is a scoping issue. 这是一个范围问题。 Generally, when creating a UserControl , you want to set itself as the DataContext for its sub-elements. 通常,在创建UserControl ,您希望将自身设置为其子元素的DataContext This is most easily accomplished in the constructor: 这在构造函数中最容易实现:

UserControlExample() {
   InitializeComponent();
   RootElement.DataContext = this;
}

Where RootElement is the name you give to this first child (usually a Grid or panel) of your UserControl . 其中RootElement是您为UserControl第一个子节点(通常是网格或面板)指定的名称。

From here you can set natural bindings for your sub-elements like so: 从这里你可以为你的子元素设置自然绑定,如下所示:

<TextBox x:Name="MainTextBox" IsEnabled={Binding IsEnabled} />

This works, since TextBox inherits the DataContext of the parent layout panel. 这是有效的,因为TextBox继承了父布局面板的DataContext

Finally, if you want to have your UserControl 's IsEnabled property to be related to its parent, this is best done at the point of declaration: 最后,如果您希望将UserControlIsEnabled属性与其父级相关联,则最好在声明时进行:

<Grid>
   <UserControlExample IsEnabled={Binding CanModify} />
</Grid>

This way you keep your concerns separate. 这样您可以将您的顾虑分开。 The sub-controls don't care what the UserControl is reflecting. 子控件不关心UserControl反映的内容。 They just need to know how to enable/disable when the control's IsEnabled property flips. 他们只需要知道在控件的IsEnabled属性翻转时如何启用/禁用。

sub-controls IsEnabled bound to --> (UserControlExample is DataContext)
   UserControlExample.IsEnabled bound to -->  (VM is DataContext)
      VM.CanModify  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM