我有一个自定义控件,我将模板应用于。在自定义控件内部,我定义了绑定到样式内模板控件的属性。如果我订阅了Loaded事件并尝试获取属性,则它们为null。但是,如果我正在使用OnPropertyChanged它们有值。有人可以解释为什么会如此。 请查看ColumnEntity属性。
谢谢。
我已删除部分内容以提供简报
<!-- This code is based on http://www.codeproject.com/KB/WPF/DataGridFilterLibrary.aspx -->
<Style TargetType="{x:Type local:DataGridColumnFilter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DataGridColumnFilter}">
<Border Background ="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBox VerticalAlignment="Top" VerticalContentAlignment="Center" Background="AliceBlue"
Text="{Binding
RelativeSource={RelativeSource AncestorType={x:Type local:DataGridColumnFilter}},
Path=QueryEntity.Text, Mode=OneWayToSource, UpdateSourceTrigger=Explicit}">
</TextBox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{ComponentResourceKey
TypeInTargetAssembly={x:Type local:DataGridColumnFilter}, ResourceId=DataGridHeaderFilterControlStyle}"
TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<local:DataGridColumnFilter Grid.Row="0"
DataGridEntity="{Binding
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=.}"
ColumnEntity="{Binding
RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}}, Path=Column}"
ItemsSourceEntity ="{Binding
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=ItemsSource}"/>
<theme:DataGridHeaderBorder Grid.Row="1"
SortDirection ="{TemplateBinding SortDirection}"
IsHovered ="{TemplateBinding IsMouseOver}"
IsPressed ="{TemplateBinding IsPressed}"
IsClickable ="{TemplateBinding CanUserSort}"
Background ="{TemplateBinding Background}"
BorderBrush ="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding ="{TemplateBinding Padding}"
SeparatorBrush ="{TemplateBinding SeparatorBrush}"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}">
<TextBlock Grid.Row="1" TextWrapping="Wrap"
Text ="{TemplateBinding Content}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment ="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
</TextBlock>
</theme:DataGridHeaderBorder>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
public class DataGridColumnFilter : Control
{
static DataGridColumnFilter()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(DataGridColumnFilter), new FrameworkPropertyMetadata(typeof(DataGridColumnFilter)));
}
public DataGridColumnFilter()
{
this.Loaded += new RoutedEventHandler(DataGridColumnFilter_Loaded);
}
void DataGridColumnFilter_Loaded(object sender, RoutedEventArgs e)
{
// here is would be null!
var controller = ColumnEntity;
}
// For some reason this seems to be the only place to access the ColumnEntity
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
if (e.Property == ItemsSourceEntityProperty && e.OldValue != e.NewValue && null != DataGridEntity && ColumnEntity is DataGridColumn)
{
// here it works fine. The property has a proper value
var controller = ColumnEntity;
}
base.OnPropertyChanged(e);
}
#region Properties
public Query QueryEntity
{
get { return (Query)GetValue(QueryEntityProperty); }
set { SetValue(QueryEntityProperty, value); }
}
public static readonly DependencyProperty QueryEntityProperty =
DependencyProperty.Register("QueryEntity", typeof(Query), typeof(DataGridColumnFilter));
public DataGridColumn ColumnEntity
{
get { return (DataGridColumn)GetValue(ColumnEntityProperty); }
set { SetValue(ColumnEntityProperty, value); }
}
public static readonly DependencyProperty ColumnEntityProperty =
DependencyProperty.Register("ColumnEntity", typeof(DataGridColumn), typeof(DataGridColumnFilter));
public DataGrid DataGridEntity
{
get { return (DataGrid)GetValue(DataGridEntityProperty); }
set { SetValue(DataGridEntityProperty, value); }
}
public static readonly DependencyProperty DataGridEntityProperty =
DependencyProperty.Register("DataGridEntity", typeof(DataGrid), typeof(DataGridColumnFilter));
public IEnumerable ItemsSourceEntity
{
get { return (IEnumerable)GetValue(ItemsSourceEntityProperty); }
set { SetValue(ItemsSourceEntityProperty, value); }
}
public static readonly DependencyProperty ItemsSourceEntityProperty =
DependencyProperty.Register("ItemsSourceEntity", typeof(IEnumerable), typeof(DataGridColumnFilter));
#endregion
}
答案 0 :(得分:0)
尝试使用OnApplyTemplate事件而不是加载事件
public override void OnApplyTemplate()
答案 1 :(得分:0)
绑定评估在构建整个Visual Tree之后的加载过程中稍后进行。不要依赖单个事件来收集值,只需在DependencyProperties上使用PropertyChanged处理程序,您已经确认它们已经为您提供了预期的值。
您还可以简化ColumnEntity以使用ColumnEntity="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Column}"