page.DataContext не унаследован от родительского фрейма?
У меня есть страница page
в frame
Frame, с frame.DataContext = "foo"
.
-
(page.Parent as Frame).DataContext
– это"foo"
. ОК - BindingExpression для
page.DataContext
имеет значениеnull
(также принудительно с ClearValue). ОК -
page.DataContext
имеет значениеnull
. но я ожидал «foo»!
Почему DataContext не унаследован? Насколько я понимаю, кадр изолирует содержимое. Но я не мог найти никакой документации по этому поведению – может ли кто-нибудь указать мне место, где это упоминается?
- Связывание Datagrid в WPF
- Можете ли вы определить несколько TargetTypes для одного стиля XAML?
- Виртуализация элемента управления ItemsControl?
- Как я могу получить положение текстового поля, которое было нажато?
- Страница vs Окно в WPF?
- Как сделать управление наложением выше всех других элементов управления?
- Создание определенного текста в текстовом поле
- WPF Canvas, как динамически добавлять детей с кодом MVVM
- Создание WPF BitmapImage из MemoryStream png, gif
- WPF - Как заставить команду переоценить «CanExecute» через свой CommandBindings
- Как прокручивать в нижней части ScrollViewer автоматически с помощью Xaml и привязки?
- Выполнение задачи в фоновом режиме в приложении WPF
- WPF TextBox для ввода десятичных значений
Чтобы ответить на ваш вопрос о документации по этому поводу: это не документация Microsoft, но у меня есть несколько книг WPF, в которых упоминаются об этом.
« Essential Windows Presentation Foundation » говорит: (стр. 160-161)
Есть две интересные модели для размещения навигационного контента: изолированный хостинг и интегрированный хостинг.
С изолированным хостингом контент не доверяется и запускается в полностью изолированной (изолированной) среде. Так размещается контент WPF при работе в веб-браузере системы как приложение браузера XAML. Для навигации к другому приложению или содержимому HTML эта изолированная модель хостинга поддерживается объектом
Frame
.Интегрированный хостинг, в котором мы хотим, чтобы контент вел себя как часть нашего приложения, вообще не поддерживается в системе. Когда
Frame
перемещается к контенту внутри приложения, мы получаем нечетный гибрид изолированного и интегрированного поведения.Frame
изолирует свой контент от его стиля (и его родительского стиля), но не от стиля приложения. События не выходят из содержимого вFrame
; однако объекты доступны из свойстваContent
(что означает, что они не изолированы в смысле безопасности).По всем этим причинам
Frame
наиболее полезен, когда мы работаем с внешним контентом, но его можно тщательно использовать для контента приложения.
Это все, что он должен сказать – ничего о наследовании собственности.
« Windows Presentation Foundation Unleashed говорит (стр. 95):
Управление
Frame
содержит произвольный контент, как и все остальные элементы управления содержимым, но изолирует контент от остальной части пользовательского интерфейса. Например, свойства, которые обычно наследуются вниз по дереву элементов, останавливаются, когда они достигаютFrame
.
Вы специально не задавались вопросом, как вы можете сделать эту работу, только почему это не по умолчанию. Однако, если вы хотите, чтобы ваши страницы наследовали DataContext Frame, вы можете сделать это:
В XAML:
В коде:
private void frame_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { UpdateFrameDataContext(sender, e); } private void frame_LoadCompleted(object sender, NavigationEventArgs e) { UpdateFrameDataContext(sender, e); } private void UpdateFrameDataContext(object sender, NavigationEventArgs e) { var content = frame.Content as FrameworkElement; if (content == null) return; content.DataContext = frame.DataContext; }
Чтобы основываться на ответе @ Joe-White для тех, кто хочет знать, как сделать каскад Frame
DataContext
, я упомянул, что это также можно выполнить только в XAML.
Для тех, кто не App.xaml
с WPF, вы можете поместить этот XAML в файл App.xaml
чтобы он App.xaml
все элементы управления Frame
в приложении, которые выбирают стиль по умолчанию. Это означает, что вам не нужно писать конкретный код при каждом использовании нового Frame
.
Я использовал VisualStudio 2015 Visual Designer (см. Рис. Ниже), чтобы создать основную часть XAML выше, а затем добавил DataContext="{TemplateBinding DataContext}"
для выполнения каскада.