gpt4 book ai didi

c# - 使用 ContentProperty 的 DataContext 直通

转载 作者:太空宇宙 更新时间:2023-11-03 15:45:10 29 4
gpt4 key购买 nike

我想创建一个自定义控件来简化以下代码:

<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>

后面的代码公开了 2 个依赖属性:

  • Text:标签的内容
  • 控件:由内容承载的控件。该类使用 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>

我遇到的问题是控件中的绑定(bind)没有映射。有没有办法解决? Label Controls 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')

最佳答案

如果您的 LabelControl 包含在 Window 中并且它的 DataContext 具有 FirstName,请尝试像这样更改您的绑定(bind)属性(property)。

<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>

...并改为更改 LabelControl 的实现。

首先,从 LabelControl 的代码隐藏中松开 DataContext 分配。

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

关于c# - 使用 ContentProperty 的 DataContext 直通,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28397267/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com