C# 自定义控件中的WPF绑定
我在WPF中有一个CustomControlC# 自定义控件中的WPF绑定,c#,.net,wpf,binding,custom-controls,C#,.net,Wpf,Binding,Custom Controls,我在WPF中有一个CustomControl [TemplatePart(Name = ControlSaveButtonName, Type = typeof(Button))] [TemplatePart(Name = ControlCancelButtonName, Type = typeof(Button))] [TemplatePart(Name = ControlPanelName, Type = typeof(Panel))] public class BaseEditEntity
[TemplatePart(Name = ControlSaveButtonName, Type = typeof(Button))]
[TemplatePart(Name = ControlCancelButtonName, Type = typeof(Button))]
[TemplatePart(Name = ControlPanelName, Type = typeof(Panel))]
public class BaseEditEntityControl : Control
{
public const string ControlSaveButtonName = "PART_SaveButton";
public const string ControlCancelButtonName = "PART_CancelButton";
public const string ControlPanelName = "PART_Panel";
static BaseEditEntityControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BaseEditEntityControl), new FrameworkPropertyMetadata(typeof(BaseEditEntityControl)));
}
private Button _saveButtonControl;
public Button SaveButtonControl
{
get { return _saveButtonControl; }
}
private Button _cancelButtonControl;
public Button CancelButtonControl
{
get { return _cancelButtonControl; }
}
private Panel _panelControl;
public Panel PanelControl
{
get { return _panelControl; }
}
public static readonly DependencyProperty EntityProperty = DependencyProperty.Register(
"Entity", typeof(object), typeof(BaseEditEntityControl));
//, new FrameworkPropertyMetadata
//{
// BindsTwoWayByDefault = true,
// PropertyChangedCallback = BaseEntityPropertyChanged
//});
public object Entity
{
get { return GetValue(EntityProperty); }
set { SetValue(EntityProperty, value); FillPropertyControls(); }
}
public BaseEditEntityControl()
{
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_saveButtonControl = GetTemplateChild(ControlSaveButtonName) as Button;
_cancelButtonControl = GetTemplateChild(ControlCancelButtonName) as Button;
_panelControl = GetTemplateChild(ControlPanelName) as Panel;
if (_saveButtonControl != null) _saveButtonControl.Click += SaveButton_Click;
if (_cancelButtonControl != null) _cancelButtonControl.Click += CancelButton_Click;
}
public void FillPropertyControls()
{
//Some Code
}
//private static void BaseEntityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
//{
// var baseEntityControl = d as BaseEditEntityControl;
// if (baseEntityControl == null) return;
//
// baseEntityControl.Entity = e.NewValue as BaseEntity;
//}
}
控制模板:
<Style x:Key="PassportEntityEditControlStyle" TargetType="{x:Type base:BaseEditEntityControl}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type base:BaseEditEntityControl}">
<StackPanel x:Name="PART_Panel" Orientation="Vertical">
<TextBlock Text="{Binding Entity, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=base:BaseEditEntityControl}}"></TextBlock>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
控件使用:
<Style TargetType="propertyControls1:PersonPassportPropertyControl">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="propertyControls1:PersonPassportPropertyControl">
<Grid ScrollViewer.CanContentScroll="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<base:BaseEditEntityControl x:Name="PART_Value" ScrollViewer.CanContentScroll="True"
Entity="{Binding PropertyBinding, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=propertyControls1:PersonPassportPropertyControl}}"
Style="{StaticResource PassportEntityEditControlStyle}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
PersonPassportPropertyControl也是一个自定义控件
问题:文本框已填充,但未调用“实体集”和FillPropertyControl。如果取消对PropertyChangedCallback的注释,则调用BaseEntityPropertyChanged。绑定不使用get和set访问器 按以下方式更改实体属性:
//Entity Dependency Property
public object Entity
{
get { return (object)GetValue(EntityProperty); }
set { SetValue(EntityProperty, value); }
}
public static readonly DependencyProperty EntityProperty =
DependencyProperty.Register("Entity", typeof(object),
typeof(BaseEditEntityControl),
new UIPropertyMetadata(null),
(d, e) => { FillPropertyControls(); });
这就是它的工作原理。文档中也明确提到,XAML绕过属性包装器,直接调用
GetValue
和SetValue
发件人:
其XAML处理器的当前WPF实现本质上是
依赖属性感知。WPF XAML处理器使用属性系统
加载二进制XAML和
正在处理作为依赖项属性的属性这很有效
绕过属性包装器。实现自定义依赖项时
属性,则必须说明此行为,并应避免
在属性包装器中放置除
属性系统方法GetValue和SetValue。
使用
PropertyChangeCallback
来放置您希望在依赖项属性更改时执行的代码。您的观察是正确的,依赖项属性在设计上既不调用setter也不调用getter。这就是为什么您的注释代码是正确的。setter/getter中唯一有效的代码是SetValue/GetValue。