Я использую DocumentGroup и DocumentGroupAdapter от DevExpress (описанный в E3339 на своем сайте) для приложения WPF с PRISM 6. Я использую области с областью видимости и INavigationAware, и все работает так, как ожидалось, I можно перейти к новым документам, и я вижу прекрасный интерфейс INavigationAware, работающий на моих моделях просмотра, точно так, как я хочу. Единственная проблема заключается в том, что фактический документ (например, вкладка в элементе управления вкладкой) не активируется (это означает, что вкладка становится видимой) при повторном перемещении во второй раз (функция INavigationAware для представлений работает должным образом).Активировать DevExpress DocumentPanel в области DocumentGroup при навигации с PRISM
ответ
Я не знаком с элементом управления DevExrpess, но у меня есть пользовательский региональный адаптер и поведение IActiveAware для элемента управления Infragistics xamDockManager. Проверьте код и посмотрите, можете ли вы изменить его для работы с вашим поставщиком контроля.
https://github.com/brianlagunas/xamDockManager-Region-Adapter
Спасибо Брайан, просматривая код сейчас. Я думаю, что «трюк» находится в методе Region.Deactivate. Действительно ли это выгружает представление из региона или оно просто обозначает представление как не активное, а сохраняет его в памяти и в регионе? – Aktaeon
Если смотреть дальше, кажется, что одна из проблем заключается в том, что адаптер группы документов реализован как AllActiveRegion. Будет проверять завтра. Спасибо за то, что указали мне, надеюсь, в правильном направлении ;-) – Aktaeon
Спасибо, Брайан! Получил его работу на основе вашего кода. – Aktaeon
Я получил это работает на основе ответа Брайана. Для всех, кто интересуется здесь, это мое решение, когда я реализую IPanelInfo на моей модели просмотра, используя сначала. Результатом является то, что при повторном переходе к уже открытой панели документов он активируется, тогда как раньше он этого не делал. Примечание плохо проверено на данный момент ;-)
public class DocumentGroupAdapter : RegionAdapterBase<DocumentGroup>
{
public DocumentGroupAdapter(IRegionBehaviorFactory behaviorFactory) :
base(behaviorFactory)
{
}
protected override IRegion CreateRegion()
{
return new SingleActiveRegion();
}
protected override void Adapt(IRegion region, DocumentGroup regionTarget)
{
region.Views.CollectionChanged += (s, e) => {
OnViewsCollectionChanged(regionTarget, e);
};
var manager = regionTarget.GetDockLayoutManager();
manager.DockItemClosing += (s, e) =>
{
Closing(region, e);
};
manager.ClosingBehavior = ClosingBehavior.ImmediatelyRemove;
}
protected override void AttachBehaviors(IRegion region, DocumentGroup regionTarget)
{
base.AttachBehaviors(region, regionTarget);
if (!region.Behaviors.ContainsKey(DocumentGroupSyncBehavior.BehaviorKey))
region.Behaviors.Add(DocumentGroupSyncBehavior.BehaviorKey, new DocumentGroupSyncBehavior() { HostControl = regionTarget });
}
private static void Closing(IRegion region, ItemEventArgs e)
{
var documentPanel = e.Item as DocumentPanel;
var view = documentPanel?.Content;
if (view == null) return;
var v = view as FrameworkElement;
var info = v?.DataContext as IPanelInfo;
info?.Close();
region.Remove(view);
}
private static void OnViewsCollectionChanged(DocumentGroup regionTarget, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
foreach (var view in e.NewItems)
{
var manager = regionTarget.GetDockLayoutManager();
var panel = manager.DockController.AddDocumentPanel(regionTarget);
panel.Content = view;
panel.ClosingBehavior = ClosingBehavior.ImmediatelyRemove;
var v = view as FrameworkElement;
var info = v?.DataContext as IPanelInfo;
if (info != null)
{
var myBinding = new Binding
{
Source = v.DataContext,
Path = new PropertyPath("Caption"),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
BindingOperations.SetBinding(panel, BaseLayoutItem.CaptionProperty, myBinding);
}
manager.DockController.Activate(panel);
}
}
}
public class DocumentGroupSyncBehavior : RegionBehavior, IHostAwareRegionBehavior
{
public const string BehaviorKey = "DocumentGroupRegionActiveAwareBehavior";
private DocumentGroup _hostControl;
public DependencyObject HostControl
{
get { return _hostControl; }
set { _hostControl = value as DocumentGroup; }
}
protected override void OnAttach()
{
_hostControl.SelectedItemChanged += HostControl_SelectedItemChanged;
Region.ActiveViews.CollectionChanged += ActiveViews_CollectionChanged;
}
private void HostControl_SelectedItemChanged(object sender, SelectedItemChangedEventArgs e)
{
if (e.OldItem != null)
{
var item = e.OldItem;
//are we dealing with a DocumentPanel directly
if (Region.Views.Contains(item) && Region.ActiveViews.Contains(item))
{
Region.Deactivate(item);
}
else
{
//now check to see if we have any views that were injected
var contentControl = item as DocumentPanel;
if (contentControl != null)
{
var injectedView = contentControl.Content;
if (Region.Views.Contains(injectedView) && Region.ActiveViews.Contains(injectedView))
Region.Deactivate(injectedView);
}
}
}
if (e.Item != null)
{
var item = e.Item;
//are we dealing with a DocumentPanel directly
if (Region.Views.Contains(item) && !Region.ActiveViews.Contains(item))
{
Region.Activate(item);
}
else
{
//now check to see if we have any views that were injected
var contentControl = item as DocumentPanel;
if (contentControl != null)
{
var injectedView = contentControl.Content;
if (Region.Views.Contains(injectedView) && !Region.ActiveViews.Contains(injectedView))
Region.Activate(injectedView);
}
}
}
}
private void ActiveViews_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
//are we dealing with a view
var frameworkElement = e.NewItems[0] as FrameworkElement;
if (frameworkElement != null)
{
var documentPanel = GetContentPaneFromView(frameworkElement);
if (documentPanel != null && !documentPanel.IsActive)
documentPanel.ActivateCommand.Execute(null);
}
else
{
//must be a viewmodel
var viewModel = e.NewItems[0];
var contentPane = GetContentPaneFromFromViewModel(viewModel);
contentPane?.ActivateCommand.Execute(null);
}
}
}
private DocumentPanel GetContentPaneFromView(object view)
{
foreach (var baseLayoutItem in _hostControl.Items)
{
var contentPane = (DocumentPanel) baseLayoutItem;
if (contentPane?.Content != null && contentPane.Content == view)
return contentPane;
}
return null;
}
private DocumentPanel GetContentPaneFromFromViewModel(object viewModel)
{
foreach (var baseLayoutItem in _hostControl.Items)
{
var contentPane = (DocumentPanel) baseLayoutItem;
var content = contentPane?.Content as FrameworkElement;
if (content != null && content.DataContext == viewModel)
return contentPane;
}
return null;
}
}
public interface IPanelInfo
{
string Caption { get; set; }
void Close();
}
Существует событие OnNavigatedTo, которое поставляется с программой INavigationAware. Вы пробовали использовать это? Я чувствую, что это сработает. –
Да, но это событие срабатывает в viewmodel не в регионе. Я хотел бы иметь возможность подключаться к событию без изменения всех типов моделей документов. – Aktaeon
и, чтобы добавить, я думаю, адаптер должен решить эту проблему, так как ответственность за обновление своего представления не влияет на элемент управления «tab», а не на модель представления, которую она размещает на вкладке. – Aktaeon