我在SilverLight中开发了一个包含多个子控件的用户控件。 Textboxes
,ComboBoxes
等等。
问题是,当我将UserControl
包含到父视图中并将完整控件设置为IsEnabled=False
时,仍会启用该特定UserControl
中的子控件。
毕竟我发现了问题。
添加类似的东西,意味着IsEnabled
绑定位于UserControl
绑定中,而不是我自己在父级的DataContext
中所期望的。
<localControls:TeamEmployeeSelector Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
IsEnabled="{Binding CanModify}" DataContext="{Binding Confidentiality}"/>
问题:
但是仍然存在如何将IsEnabled
绑定到Parent的ViewModel的问题?因为将CanModify
属性复制到子控件的ViewModel并不是很优雅。
答案 0 :(得分:6)
而不是以某种方式修改绑定(例如,您可以使其依赖于其他答案中提出的其他控件名称),我将单独移动将被禁用的控件并控制DataContext
将在哪里改变了。例如:
<ContentControl IsEnabled="{Binding CanModify}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<localControls:TeamEmployeeSelector DataContext="{Binding Confidentiality}"/>
</ContentControl>
答案 1 :(得分:1)
我将如何做到这一点。
您的TeamEmployeeSelector
UserControl
将包含一个根级别元素,默认情况下为Grid
,并且名称为“LayoutRoot”。
现在,您可以将所有子元素的IsEnabled
属性绑定到UserControl
,如下所示: -
<TextBox IsEnabled="{Binding Parent.IsEnabled, ElementName=LayoutRoot}" ... />
通过使用元素到元素绑定,您无需将CanModify
属性复制到子视图模型中。
有些人可能会建议您只是向UserControl元素添加x:Name
,然后直接绑定到它,而不是像上面那样通过根元素的Parent
属性。这在Silverlight 4中可以正常工作,但在3或WP7中没有。我个人更喜欢上述内容。
答案 2 :(得分:0)
答案 3 :(得分:0)
<localControls:TeamEmployeeSelector Grid.Row="1" Grid.Column="0"
Grid.ColumnSpan="2" IsEnabled="{Binding ElementName=SomeElementName_With_Parent_ViewModel, Path=DataContext.CanModify}" DataContext="{Binding Confidentiality}"/>
答案 4 :(得分:0)
这是一个范围问题。通常,在创建UserControl
时,您希望将其自身设置为其子元素的DataContext
。这在构造函数中最容易实现:
UserControlExample() {
InitializeComponent();
RootElement.DataContext = this;
}
RootElement
是您UserControl
的第一个孩子(通常是网格或面板)的名称。{/ 1>
从这里你可以设置子元素的自然绑定,如下所示:
<TextBox x:Name="MainTextBox" IsEnabled={Binding IsEnabled} />
这是有效的,因为TextBox
会继承父布局面板的DataContext
。
最后,如果您希望将UserControl
的{{1}}属性与其父级相关联,则最好在声明时进行:
IsEnabled
通过这种方式,您可以将您的疑虑分开。子控件不关心<Grid>
<UserControlExample IsEnabled={Binding CanModify} />
</Grid>
反映的内容。他们只需要知道在控件的UserControl
属性翻转时如何启用/禁用。
IsEnabled