从内部控件绑定控件属性
Bind control property from the inner control
我有一个包含另一个控件的控件。 InnerControl 包含一些 属性,例如 ButtonVisibility。简化的 InnerControl 代码示例如下
public class InnerControl : ControlBase
{
//...
public Visibility ButtonVisibility
{
get { return (Visibility)GetValue(ButtonVisibility); }
set { SetValue(ButtonVisibility, value); }
}
public static readonly DependencyProperty ButtonVisibility =
DependencyProperty.Register(
"ButtonVisibility",
typeof (Visibility),
typeof (InnerControl),
new PropertyMetadata(Visibility.Collapsed));
}
这是包含 InnerControl 作为依赖项的 MainControl 代码 属性
public class MainControl : ControlBase
{
//...
public InnerControl MyInner
{
get { return (InnerControl) GetValue(MyInnerProperty); }
set { SetValue(MyInnerProperty, value); }
}
public static readonly DependencyProperty MyInnerProperty =
DependencyProperty.Register(
"MyInner",
typeof (InnerControl),
typeof (MainControl),
new PropertyMetadata(null, OnMyInnerPropertyChanged));
private static void OnMyInnerPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//...
}
}
我在 Generic.xaml
中有两个不同的控件模板
<Style TargetType="local:InnerControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:InnerControl">
<Grid x:Name="ContainerGrid">
<!-- some markup -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:MainControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MainControl">
<Grid x:Name="RootGrid">
<Button x:Name="MyButton" Visibility="{TemplateBinding ???}"/>
<ContentControl x:Name="MyInnerControl" Content="{TemplateBinding MyInner}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这就是我如何使用此控件的方式
<controls:MainControl>
<controls:MainControl.MyInner>
<controls:InnerControl ButtonVisibility="Visible">
<!-- some markup -->
</controls:InnerControl>
</controls:MainControl.MyInner>
<!-- some markup -->
</controls:MainControl>
我需要在单击按钮后更改 MainControl
的状态。这就是它位于 MainControl
模板中的原因。
那么,任何人都可以建议我如何将 ButtonVisibility
从 MyInner
绑定到 MainControl
上的 MyButton
吗?
WPF 附加属性有助于从内部控件更改主控件的状态。
你需要直接绑定到InnerControl的"ButtonVisibility" 属性,像这样:
<Button x:Name="MyButton"
Visibility="{Binding MyInner.ButtonVisibility,
RelativeSource={RelativeSource TemplatedParent}}"/>
就像@james 提到的那样,您必须使用 RelativeSource 绑定到 TemplatedParent 或可视化树中的任何类型,方法是指定如下类型:
<Button x:Name="MyButton" Content="MyButton"
Visibility="{Binding Path=MyInner.ButtonVisibility,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type controls:MainControl}}}"/>
我有一个包含另一个控件的控件。 InnerControl 包含一些 属性,例如 ButtonVisibility。简化的 InnerControl 代码示例如下
public class InnerControl : ControlBase
{
//...
public Visibility ButtonVisibility
{
get { return (Visibility)GetValue(ButtonVisibility); }
set { SetValue(ButtonVisibility, value); }
}
public static readonly DependencyProperty ButtonVisibility =
DependencyProperty.Register(
"ButtonVisibility",
typeof (Visibility),
typeof (InnerControl),
new PropertyMetadata(Visibility.Collapsed));
}
这是包含 InnerControl 作为依赖项的 MainControl 代码 属性
public class MainControl : ControlBase
{
//...
public InnerControl MyInner
{
get { return (InnerControl) GetValue(MyInnerProperty); }
set { SetValue(MyInnerProperty, value); }
}
public static readonly DependencyProperty MyInnerProperty =
DependencyProperty.Register(
"MyInner",
typeof (InnerControl),
typeof (MainControl),
new PropertyMetadata(null, OnMyInnerPropertyChanged));
private static void OnMyInnerPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//...
}
}
我在 Generic.xaml
中有两个不同的控件模板<Style TargetType="local:InnerControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:InnerControl">
<Grid x:Name="ContainerGrid">
<!-- some markup -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:MainControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MainControl">
<Grid x:Name="RootGrid">
<Button x:Name="MyButton" Visibility="{TemplateBinding ???}"/>
<ContentControl x:Name="MyInnerControl" Content="{TemplateBinding MyInner}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这就是我如何使用此控件的方式
<controls:MainControl>
<controls:MainControl.MyInner>
<controls:InnerControl ButtonVisibility="Visible">
<!-- some markup -->
</controls:InnerControl>
</controls:MainControl.MyInner>
<!-- some markup -->
</controls:MainControl>
我需要在单击按钮后更改 MainControl
的状态。这就是它位于 MainControl
模板中的原因。
那么,任何人都可以建议我如何将 ButtonVisibility
从 MyInner
绑定到 MainControl
上的 MyButton
吗?
WPF 附加属性有助于从内部控件更改主控件的状态。
你需要直接绑定到InnerControl的"ButtonVisibility" 属性,像这样:
<Button x:Name="MyButton"
Visibility="{Binding MyInner.ButtonVisibility,
RelativeSource={RelativeSource TemplatedParent}}"/>
就像@james 提到的那样,您必须使用 RelativeSource 绑定到 TemplatedParent 或可视化树中的任何类型,方法是指定如下类型:
<Button x:Name="MyButton" Content="MyButton"
Visibility="{Binding Path=MyInner.ButtonVisibility,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type controls:MainControl}}}"/>