Custom dependency property not working
I have a panorama control whose data template is as follows:-
<DataTemplate x:Key="DataTemplateCategory">
<Grid >
<localControls:PanoramaItem BookmarkedTopics="{Binding Path=BookmarkedTopics,ElementName=root}" Topics="{Binding Topics}"/>
</Grid>
</DataTemplate>
The root is 开发者_JAVA百科the name of the usercontrol in which the panorama is defined. and BookmarkedTopics in Path is DependencyProperty in root (usercontrol) whose definition is as follows:-
public static readonly DependencyProperty BookmarkedTopicsProperty = DependencyProperty.Register("BookmarkedTopics",
typeof(ObservableCollection<Topic>), typeof(MainPage), new PropertyMetadata(new ObservableCollection<Topic>()));
public ObservableCollection<Topic> BookmarkedTopics
{
get { return GetValue(BookmarkedTopicsProperty) as ObservableCollection<Topic>; }
set
{
SetValue(BookmarkedTopicsProperty, value);
}
}
BookmarkedTopics gets set in MainPage_Loaded and it never null or empty collection (irrelevant to my question but still thought to mention it). BookmarkedTopics is Dependency property in PanoramaItem also whose definition is:-
public static readonly DependencyProperty BookmarkedTopicsProperty = DependencyProperty.Register("BookmarkedTopics",
typeof(ObservableCollection<Topic>), typeof(PanoramaItem), new PropertyMetadata(new ObservableCollection<Topic>()));
public ObservableCollection<Topic> BookmarkedTopics
{
get { return GetValue(BookmarkedTopicsProperty) as ObservableCollection<Topic>; }
set
{
SetValue(BookmarkedTopicsProperty, value);
}
}
Problem is when the the BookmarkedTopics get set in MainPage_Loaded why is the setter of BookmarkedTopics in PanoramaItem not fired? Any bug that you can see in the code?
Thanks in advance :)
When a dependency property value is assigned by a binding or an animation Silverlight uses the SetValue
method directly using the appropriate DependencyProperty
static field. Hence the setter method of the POCO property is not called.
If you need code to run when a dependency property is assigned you need to use code like this:-
public ObservableCollection<Topic> BookmarkedTopics
{
get { return GetValue(BookmarkedTopicsProperty) as ObservableCollection<Topic>; }
set { SetValue(BookmarkedTopicsProperty, value); }
}
public static readonly DependencyProperty BookmarkedTopicsProperty =
DependencyProperty.Register(
"BookmarkedTopics",
typeof(ObservableCollection<Topic>),
typeof(MainPage),
new PropertyMetadata(null, OnBookmarkedTopicsPropertyChanged));
private static void OnBookmarkedTopicsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MainPage source = d as MainPage;
ObservableCollection<Topic> value = e.NewValue as ObservableCollection<Topic>;
// Code here to handle any work when the value has changed
}
Note also the default value for this dependency property is null
. Do not use an instance of a mutable type for a dependency property default because that one instance is then shared by all instances of your class.
I know there are issues with using ObservableCollection types in dependancy properties and I know for sure you shouldn't give it a default value of a new ObservableCollection. Instead you should register it as ReadOnly (note this doesn't just mean make the definition of it read only).
This MSDN post describes it in more detail. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e19f9f98-9007-4dbd-b1c4-664a511c0846/
精彩评论