В полном раскрытии я работаю над тем, чтобы адаптировать некоторый код из другого приложения, разработанного более старшим разработчиком, для работы с моим проектом, поэтому готовьтесь к некоторой, очевидно, упущенной из виду проблеме, поскольку я изучаю WPF с головокружительной скоростью. Я знаю, что довольно много людей пытаются реализовать подобный пользовательский элемент управления, но я не видел, чтобы кто-нибудь еще сталкивался с этой проблемой.
У меня есть пользовательский элемент управления, который функционирует как боковая панель навигации, которая позволяет пользователю выбирать из списка опций слева и отображает результат в панели сетки справа. Для правого контента я разработал абстрактный базовый класс под названием BaseSectionView
, который наследуется от ContentControl
и содержит несколько сигналов (таких как занятые спиннеры, обработчики событий всплывающего окна и т. Д. c.), Которые я хочу использовать во всем приложении.
Я наследую от BaseSectionView
, чтобы создать определенный c раздел, который может отображаться в элементе ContentControl на правой панели моего ListNavigationControl
.
Здесь находятся два проекта: проект для моих пользовательских элементов управления в одном пространстве имен, для которого определен шаблон c .xaml, и проект, реализующий все эти вещи конкретно.
Объявление BaseSectionView
:
namespace my.custom.control.namespace
{
public abstract class BaseSectionView : ContentControl, INotifyPropertyChanged, IDisposable {
...
}
}
BaseSectionView
не имеет xaml, но получает информацию о стиле и шаблоне из generi c .xaml в моем проекте пользовательского элемента управления.
Следующий элемент управления наследуется от BaseSectionView
. Когда я впервые попробовал это, я объявил BaseSectionView
в качестве базового класса в ОБА XAML и коде позади, и это вызвало странную проблему. Теперь я делаю это только в xaml.
<Controls:BaseSectionView x:Class="my.implemented.control.nameSpace.MySectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:my.implemented.control.namespace"
xmlns:Controls="clr-namespace:my.custom.control.namespace"
mc:Ignorable="d">
... some uninteresting markup ...
</Controls:BaseSectionView>
Код объявления:
public partial class MySectionView
{
public MySectionView(...) : base(...)
{
...
InitializeComponent();
}
...
}
Наконец, код ListNavigationControl
(я выделил строку, которая важна для этого вопроса). Я просто показываю фрагмент кода, который обрабатывает пользователь, щелкающий по различным элементам навигации в виде списка слева, и устанавливает представление <ContentControl Name="SelectedSectionViewer" Grid.Column="2" />
в xaml.
namespace my.custom.control.namespace
{
public partial class ListNavigationControl : UserControl
{
... constructors and such ...
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_updatingSelectedSectionInternal && e.AddedItems.Count > 0)
{
BaseSectionView newSection = e.AddedItems[0] as BaseSectionView;
if (newSection != null)
{
_updatingSelectedSectionInternal = true;
// Set new page as active
_selectedSection.Model.IsActive = false;
_selectedSection = newSection;
SelectedSectionViewer.Content = _selectedSection; // <-------- This line is significant.
_selectedSection.Model.IsActive = true;
_updatingSelectedSectionInternal = false;
}
}
}
...
}
}
Во-первых, позвольте мне подчеркнуть : теперь все отлично работает но я понятия не имею, почему он был сломан раньше, и это может укусить меня позже.
Когда я с избыточностью объявлял базовый класс MySectionView
в и xaml, и код позади (что, как я понимаю, является ошибкой), я все еще мог заставить это работать (albietly badly: информация о файле generi c .xaml не будет применяться к базовому контролю и другим симптомам). Однако чтобы заставить его работать, мне пришлось изменить отмеченную строку выше на:
SelectedSectionViewer.Content = _selectedSection.Conent
В противном случае ничто не будет отображаться в элементе SelectedSectionViewer.
Здесь есть два вопроса:
A) Почему объявление базового класса моего конкретного представления как в xaml, так и в коде позади не позволило SelectedSectionViewer
выше отобразить представление ( и запретить применение информации стиля в generi c .xaml в классе пользовательских элементов управления к пользовательскому элементу управления)?
B) В чем именно разница между получением содержимого из представления с использованием свойства .Content и если потребляющий элемент отображает сам контент?
Я надеюсь, что это не слишком сложный вопрос, но до того, как я удалил эту избыточность, я много боролся с этим, и я хотел бы знать, как я возился здесь. В ближайшем будущем я попытаюсь сделать гораздо больше подобных вещей.