我想创建一个自定义控件来简化以下代码:
<StackPanel>
<DockPanel LastChildFill="True">
<Label>First Name</Label>
<TextBox Margin="2" Text="{Binding Path=FirstName}"></TextBox>
</DockPanel>
<DockPanel LastChildFill="True">
<Label>Last Name</Label>
<TextBox Margin="2" Text="{Binding Path=LastName}"></TextBox>
</DockPanel>
</StackPanel>我的想法是像下面这样制作一个UserControl (布局有点不同,但超出了范围):
<UserControl x:Class="LabelControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel LastChildFill="True">
<Label Content="{Binding Path=Text}" Margin="2" MinWidth="100" HorizontalContentAlignment="Right"></Label>
<Grid Margin="2">
<ContentControl Content="{Binding Path=Control}" ></ContentControl>
</Grid>
</DockPanel>
</UserControl>后面的代码公开了两个依赖项属性:
ContentProperty属性将子级映射到ContentControl。这样我就可以简化我的StackPanel
<StackPanel>
<controls:LabelControl Text="First Name">
<TextBox Text="{Binding Path=FirstName}"></TextBox>
</controls:LabelControl>
<controls:LabelControl Text="Last Name">
<TextBox Text="{Binding Path=LastName}"></TextBox>
</controls:LabelControl>
</StackPanel>我正在运行的问题是控件中的绑定不是映射。有办法绕过这件事吗?标签控件DataContext正在覆盖父控件上下文。
下面是LabelControl的代码:
[ContentProperty("Control")]
public partial class LabelControl : UserControl
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(LabelControl), new PropertyMetadata(default(string)));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty ControlProperty =
DependencyProperty.Register("Control", typeof(Control), typeof(LabelControl), new PropertyMetadata(default(Control)));
public Control Control
{
get { return (Control)GetValue(ControlProperty); }
set { SetValue(ControlProperty, value); }
}
public LabelControl()
{
InitializeComponent();
this.DataContext = this;
}
}编辑:输出确认数据文本正在重写。
BindingExpression path error: 'FirstName' property not found on 'object' ''LabelControl' (Name='')'. BindingExpression:Path=FirstName; DataItem='LabelControl' (Name=''); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')发布于 2015-02-08 18:07:12
如果您的LabelControl包含在Window中,并且它的DataContext具有FirstName属性,请尝试像这样更改绑定。
<TextBox Text="{Binding Path=FirstName,
RelativeSource={RelativeSource AncestorType=Window}}">
</TextBox>如果您不想每次指定RelativeSource,您可以像现在一样使用LabelControl .
<StackPanel>
<controls:LabelControl Text="First Name">
<TextBox Text="{Binding Path=FirstName}"></TextBox>
</controls:LabelControl>
<controls:LabelControl Text="Last Name">
<TextBox Text="{Binding Path=LastName}"></TextBox>
</controls:LabelControl>
</StackPanel>...and将更改LabelControl的实现。
首先,从DataContext的代码背后释放LabelControl分配。
public LabelControl()
{
InitializeComponent();
//this.DataContext = this; // we don't want this
}然后将XAML模板更改为
<DockPanel LastChildFill="True">
<Label Content="{Binding Path=Text,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
Margin="2" MinWidth="100" HorizontalContentAlignment="Right">
</Label>
<Grid Margin="2">
<ContentControl
Content="{Binding Path=Control,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
</ContentControl>
</Grid>
</DockPanel>现在您应该正确设置您的DataContext。
发布于 2015-02-09 13:03:28
我发现使用UserControl不是最理想的解决方案。事实证明,模板化控件允许DataBinds在没有任何黑客(RelativeSource)的情况下通过。
[ContentProperty("Control")]
public class LabelControl : Control
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text",
typeof(string), typeof(LabelControl), new PropertyMetadata(default(string)));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty ControlProperty =
DependencyProperty.Register("Control", typeof(Control), typeof(LabelControl), new PropertyMetadata(default(Control)));
public Control Control
{
get { return (Control)GetValue(ControlProperty); }
set { SetValue(ControlProperty, value); }
}
}在app.xaml中:
<Style TargetType="controls:LabelControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:LabelControl">
<DockPanel LastChildFill="True">
<Label Content="{TemplateBinding Text}" MinWidth="100" FontSize="11"></Label>
<Grid Margin="2">
<ContentControl Content="{TemplateBinding Control}"></ContentControl>
</Grid>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>https://stackoverflow.com/questions/28397267
复制相似问题