#c# #silverlight #windows-phone-7
#c# #silverlight #windows-phone-7
Вопрос:
У меня есть элемент управления panorama, шаблон данных которого выглядит следующим образом:-
<DataTemplate x:Key="DataTemplateCategory">
<Grid >
<localControls:PanoramaItem BookmarkedTopics="{Binding Path=BookmarkedTopics,ElementName=root}" Topics="{Binding Topics}"/>
</Grid>
</DataTemplate>
Корень — это имя пользовательского элемента управления, в котором определена панорама. и BookmarkedTopics в Path — это свойство DependencyProperty в root (usercontrol), определение которого выглядит следующим образом:-
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 устанавливается в MainPage_Loaded, и оно никогда не имеет значения null или empty collection (не имеет отношения к моему вопросу, но все же подумал упомянуть об этом). BookmarkedTopics — это свойство зависимости в PanoramaItem, определение которого также:-
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);
}
}
Проблема в том, что когда BookmarkedTopics устанавливается в MainPage_Loaded, почему установщик BookmarkedTopics в PanoramaItem не запускается? Какая-либо ошибка, которую вы можете увидеть в коде?
Заранее спасибо 🙂
Комментарии:
1. Работает ли код в любом случае? Хотя вопрос, похоже, сосредоточен на реализации свойства (что неверно и нуждается в исправлении) Я подозреваю, что реальная проблема заключается в привязке. Есть ли шаблон данных в MainPage.xaml?
2. @AnthonyWJones: — Да, это есть в MainPage.xaml.
Ответ №1:
Когда значение свойства зависимости присваивается привязкой или анимацией, Silverlight использует SetValue
метод напрямую, используя соответствующее DependencyProperty
статическое поле. Следовательно, метод установки свойства POCO не вызывается.
Если вам нужен код для запуска при назначении свойства зависимости, вам нужно использовать код, подобный этому:-
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
}
Обратите внимание также, что значение по умолчанию для этого свойства зависимости равно null
. Не используйте экземпляр изменяемого типа для свойства зависимости по умолчанию, потому что тогда этот экземпляр будет общим для всех экземпляров вашего класса.
Комментарии:
1. — Очень хорошо объяснено. Быстро пришло мне в голову. Вы должны быть преподавателем. Все ваши ответы относятся к делу и отлично решают проблему.
Ответ №2:
Я знаю, что есть проблемы с использованием типов ObservableCollection в свойствах зависимости, и я точно знаю, что вы не должны присваивать ему значение по умолчанию для новой ObservableCollection. Вместо этого вы должны зарегистрировать его как доступное только для чтения (обратите внимание, это не просто означает, что его определение доступно только для чтения).
В этом сообщении MSDN это описано более подробно. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e19f9f98-9007-4dbd-b1c4-664a511c0846 /
Комментарии:
1. Я не понял, о чем вы говорите. В WP7 Silverlight нет такого статического метода, как RegisterReadOnly. Также решит ли использование этого метода мою проблему?
2. Он говорит, что если вы используете тип коллекции в свойстве зависимости, то каждый раз, когда вы устанавливаете значение, вы уничтожаете исходную коллекцию, поскольку она удалена и заменена новой, а не редактируете оригинал. чтобы исправить это, создайте свойство только для чтения, содержащее коллекцию, чтобы первоначальную коллекцию нельзя было удалить, только отредактировать