AvalonDock 的 DocumentPane 和 DockingPane 的 Prism2 区域适配器?

发布于 2024-07-22 05:05:00 字数 70 浏览 5 评论 0原文

有人有关于如何为 AvalonDock 的 DocumentPane 和 DockingPane 创建区域适配器的示例代码吗?

Does anyone have sample code on how to create a Region Adapter for AvalonDock's DocumentPane and DockingPane?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

望喜 2024-07-29 05:05:00

Markus Raufer 已将两个区域适配器添加到 CompositeWpfContrib 项目,网址为 CodePlex 同时支持 DocumentPaneDockingPane

The Markus Raufer has added two region adapters to the CompositeWpfContrib project at CodePlex that supports both DocumentPane and DockingPane.

GRAY°灰色天空 2024-07-29 05:05:00

我已经使用了 Raffaeu Bermuda 片段支持 Avalon tab 区域适配器,但发现有一些问题没有解决:

1- 它不支持 Activating a a certain view (aka - tab - DockableContent),所以代码 Region .Activate(object view) 将不起作用。

2- 默认情况下,该区域中的所有选项卡均处于活动状态。 所以 Region.ActiveViews 集合默认包含所有视图,这并不理想,因为有时我需要验证视图是否处于活动状态(您可以想象工具栏区域上的保存按钮仅在当前活动视图 = 选项卡(在我们的例子中)上执行 SaveCommand)

3- 关闭的视图实际上并未关闭,只是隐藏。 即使您在添加 newDockableContent 时设置了 HideOnClose = true,它仍然不会从 Region.Views 集合中删除。 这可能会导致内存泄漏问题。

4-如果您之前在窗格中添加了 DockableContent,它们将不会同步并添加到 Region.Views 集合中。

下面是我现在使用的代码,它只是 PRISM 源代码中的选择器适配器和选择器同步行为的一个小调整:

AvalonRegionAdapter 类:

public class AvalonRegionAdapter : RegionAdapterBase<DocumentPane>
{
    public AvalonRegionAdapter(IRegionBehaviorFactory factory) : base(factory) {}

    protected override void AttachBehaviors(IRegion region, DocumentPane regionTarget)
    {
        if (region == null) throw new System.ArgumentNullException("region");
        //Add the behavior that syncs the items source items with the rest of the items
        region.Behaviors.Add(AvalonDocumentSyncBehavior.BehaviorKey,
                             new AvalonDocumentSyncBehavior()
        {
            HostControl = regionTarget
        });
        base.AttachBehaviors(region, regionTarget);
    }

    protected override void Adapt(IRegion region, DocumentPane regionTarget){ }

    protected override IRegion CreateRegion()
    {
        return new Region();
    }
}

AvalonDocumentSyncBehavior 行为代码:

public class AvalonDocumentSyncBehavior : RegionBehavior, IHostAwareRegionBehavior
{
    /// <summary>
    /// Name that identifies the SelectorItemsSourceSyncBehavior behavior in a collection of RegionsBehaviors. 
    /// </summary>
    public static readonly string BehaviorKey = "AvalonDocumentSyncBehavior";
    private bool updatingActiveViewsInHostControlSelectionChanged;
    private Selector hostControl;

    /// <summary>
    /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
    /// </summary>
    /// <value>
    /// A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
    /// </value>
    /// <remarks>For this behavior, the host control must always be a <see cref="Selector"/> or an inherited class.</remarks>
    public DependencyObject HostControl
    {
        get
        {
            return this.hostControl;
        }

        set
        {
            this.hostControl = value as Selector;
        }
    }

    /// <summary>
    /// Starts to monitor the <see cref="IRegion"/> to keep it in synch with the items of the <see cref="HostControl"/>.
    /// </summary>
    protected override void OnAttach()
    {
        bool itemsSourceIsSet = this.hostControl.ItemsSource != null;
        if (itemsSourceIsSet)
        {
            //throw new InvalidOperationException(Resources.ItemsControlHasItemsSourceException);
        }

        this.SynchronizeItems();

        this.hostControl.SelectionChanged += this.HostControlSelectionChanged;
        this.Region.ActiveViews.CollectionChanged += this.ActiveViews_CollectionChanged;
        this.Region.Views.CollectionChanged += this.Views_CollectionChanged;
    }

    private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            int startIndex = e.NewStartingIndex;
            foreach (object newItem in e.NewItems)
            {
                UIElement view = newItem as UIElement;
                TabViewModel viewModel = ((UserControl)view).DataContext as TabViewModel;
                if (view != null)
                {
                    DockableContent newDockableContent = new DockableContent();
                    newDockableContent.Content = newItem;
                    //if associated view has metadata then apply it.
                    newDockableContent.Title = view.GetType().ToString();
                    if (viewModel != null)
                    {
                        //Image img = new Image();
                        //img.Source = new BitmapImage(new Uri(@"Resources/Alerts.png", UriKind.Relative));
                        newDockableContent.Title = viewModel.TabModel.Title;
                        newDockableContent.IsCloseable = viewModel.TabModel.CanClose;
                        //newContentPane.Icon = img.Source;
                    }

                    //When contentPane is closed remove from the associated region
                    newDockableContent.Closed += new EventHandler(newDockableContent_Closed);

                    newDockableContent.HideOnClose = false; 
                    this.hostControl.Items.Add(newDockableContent);
                    newDockableContent.Activate();
                }
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (object oldItem in e.OldItems)
            {
                this.hostControl.Items.Remove(oldItem);
            }
        }
    }

    void newDockableContent_Closed(object sender, EventArgs e)
    {
        var dockableContent = sender as DockableContent;
        if(dockableContent != null)
            if (this.Region.Views.Contains(dockableContent.Content))
            {
                this.Region.Remove(dockableContent.Content);
            }
    }

    private void SynchronizeItems()
    {
        List<object> existingItems = new List<object>();

        // Control must be empty before "Binding" to a region
        foreach (object childItem in this.hostControl.Items)
        {
            existingItems.Add(childItem);
        }

        foreach (object view in this.Region.Views)
        {
            this.hostControl.Items.Add(view);
        }

        foreach (object existingItem in existingItems)
        {
            this.Region.Add(existingItem);
        }
    }


    private void ActiveViews_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (this.updatingActiveViewsInHostControlSelectionChanged)
        {
            // If we are updating the ActiveViews collection in the HostControlSelectionChanged, that 
            // means the user has set the SelectedItem or SelectedItems himself and we don't need to do that here now
            return;
        }

        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            var selectedDockableContent = this.hostControl.SelectedItem as DockableContent;
            if (selectedDockableContent != null
                && selectedDockableContent.Content != null
                && selectedDockableContent.Content != e.NewItems[0]
                && this.Region.ActiveViews.Contains(selectedDockableContent.Content))
            {
                this.Region.Deactivate(selectedDockableContent.Content);
            }

            var _UIElement = e.NewItems[0] as FrameworkElement;
            this.hostControl.SelectedItem = _UIElement.Parent;
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove &&
                 e.OldItems.Contains(this.hostControl.SelectedItem))
        {
            this.hostControl.SelectedItem = null;
        }
    }

    private void HostControlSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        try
        {
            // Record the fact that we are now updating active views in the HostControlSelectionChanged method. 
            // This is needed to prevent the ActiveViews_CollectionChanged() method from firing. 
            this.updatingActiveViewsInHostControlSelectionChanged = true;

            object source;
            source = e.OriginalSource;

            if (source == sender)
            {
                foreach (object item in e.RemovedItems)
                {
                    // check if the view is in both Views and ActiveViews collections (there may be out of sync)
                    var dockableContent = item as DockableContent;
                    if (this.Region.Views.Contains(dockableContent.Content) && this.Region.ActiveViews.Contains(dockableContent.Content))
                    {
                        this.Region.Deactivate(dockableContent.Content);
                    }
                }

                foreach (object item in e.AddedItems)
                {
                    var dockableContent = item as DockableContent;
                    if (this.Region.Views.Contains(dockableContent.Content) && 
                         !this.Region.ActiveViews.Contains(dockableContent.Content))
                    {
                        this.Region.Activate(dockableContent.Content);
                    }
                }
            }
        }
        finally
        {
            this.updatingActiveViewsInHostControlSelectionChanged = false;
        }
    }
}

在引导程序上配置适配器的代码

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    var mappings = base.ConfigureRegionAdapterMappings();
    mappings.RegisterMapping(typeof(AvalonDock.DocumentPane), 
                             this.Container.Resolve<AvalonRegionAdapter>());
    return mappings;
}

然后您需要 TabModel 和 TabViewModel,如 Raffaeu Bermuda

public sealed class TabModel : DependencyObject
{
   public string Title
   {
       get { return (string)GetValue(TitleProperty); }
       set { SetValue(TitleProperty, value); }
   }

   // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty TitleProperty =
       DependencyProperty.Register("Title", typeof(string), typeof(TabModel));

   public bool CanClose
   {
       get { return (bool)GetValue(CanCloseProperty); }
       set { SetValue(CanCloseProperty, value); }
   }

   // Using a DependencyProperty as the backing store for CanClose.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty CanCloseProperty =
       DependencyProperty.Register("CanClose", typeof(bool), typeof(TabModel));

   public bool IsModified
   {
       get { return (bool)GetValue(IsModifiedProperty); }
       set { SetValue(IsModifiedProperty, value); }
   }

   // Using a DependencyProperty as the backing store for IsModified.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty IsModifiedProperty =
       DependencyProperty.Register("IsModified", typeof(bool), typeof(TabModel));

}

和一个作为基类的 TabViewModel:

public class TabViewModel : INotifyPropertyChanged
{
    private TabModel _tabModel;

    public TabModel TabModel
    {
        get { return this._tabModel; }
        set
        {
            this._tabModel = value;
            OnPropertyChanged("TabModel");
        }
    }
    public TabViewModel()
    {
        this.TabModel = new TabModel();
        this.TabModel.CanClose = true;
        this.TabModel.IsModified = false;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

如果您需要进一步的帮助,请告诉我,我将在不久的将来发布一篇博客。

I have used Raffaeu Bermuda snippets to support Avalon tab region adapter, but found that there is some issues are not solved:

1- It does not support Activating a a certain view (aka - tab - DockableContent), so the code Region.Activate(object view) will not work.

2- All the Tabs are active by default in the region. So Region.ActiveViews collection by default has all the views, this is not ideal, as sometimes I needed to verify if a view is active or not (you could imagine a save button on a tool bar region that executes a SaveCommand only on the current active view = tab in our case)

3- Closed views doesn't actually get closed, only hidden. Even if you set the HideOnClose = true when adding the newDockableContent, it is still not removed from Region.Views collection. This could lead to memory leaks issues.

4- If you have a previously added DockableContent in the Pane, they will not get synchronized and added to the Region.Views collection.

So here are the code I am using now, it is just a small tweak from the Selector Adapter and Selector Sync Behavior found in PRISM source code:

AvalonRegionAdapter Class:

public class AvalonRegionAdapter : RegionAdapterBase<DocumentPane>
{
    public AvalonRegionAdapter(IRegionBehaviorFactory factory) : base(factory) {}

    protected override void AttachBehaviors(IRegion region, DocumentPane regionTarget)
    {
        if (region == null) throw new System.ArgumentNullException("region");
        //Add the behavior that syncs the items source items with the rest of the items
        region.Behaviors.Add(AvalonDocumentSyncBehavior.BehaviorKey,
                             new AvalonDocumentSyncBehavior()
        {
            HostControl = regionTarget
        });
        base.AttachBehaviors(region, regionTarget);
    }

    protected override void Adapt(IRegion region, DocumentPane regionTarget){ }

    protected override IRegion CreateRegion()
    {
        return new Region();
    }
}

AvalonDocumentSyncBehavior Behavior Code:

public class AvalonDocumentSyncBehavior : RegionBehavior, IHostAwareRegionBehavior
{
    /// <summary>
    /// Name that identifies the SelectorItemsSourceSyncBehavior behavior in a collection of RegionsBehaviors. 
    /// </summary>
    public static readonly string BehaviorKey = "AvalonDocumentSyncBehavior";
    private bool updatingActiveViewsInHostControlSelectionChanged;
    private Selector hostControl;

    /// <summary>
    /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
    /// </summary>
    /// <value>
    /// A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
    /// </value>
    /// <remarks>For this behavior, the host control must always be a <see cref="Selector"/> or an inherited class.</remarks>
    public DependencyObject HostControl
    {
        get
        {
            return this.hostControl;
        }

        set
        {
            this.hostControl = value as Selector;
        }
    }

    /// <summary>
    /// Starts to monitor the <see cref="IRegion"/> to keep it in synch with the items of the <see cref="HostControl"/>.
    /// </summary>
    protected override void OnAttach()
    {
        bool itemsSourceIsSet = this.hostControl.ItemsSource != null;
        if (itemsSourceIsSet)
        {
            //throw new InvalidOperationException(Resources.ItemsControlHasItemsSourceException);
        }

        this.SynchronizeItems();

        this.hostControl.SelectionChanged += this.HostControlSelectionChanged;
        this.Region.ActiveViews.CollectionChanged += this.ActiveViews_CollectionChanged;
        this.Region.Views.CollectionChanged += this.Views_CollectionChanged;
    }

    private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            int startIndex = e.NewStartingIndex;
            foreach (object newItem in e.NewItems)
            {
                UIElement view = newItem as UIElement;
                TabViewModel viewModel = ((UserControl)view).DataContext as TabViewModel;
                if (view != null)
                {
                    DockableContent newDockableContent = new DockableContent();
                    newDockableContent.Content = newItem;
                    //if associated view has metadata then apply it.
                    newDockableContent.Title = view.GetType().ToString();
                    if (viewModel != null)
                    {
                        //Image img = new Image();
                        //img.Source = new BitmapImage(new Uri(@"Resources/Alerts.png", UriKind.Relative));
                        newDockableContent.Title = viewModel.TabModel.Title;
                        newDockableContent.IsCloseable = viewModel.TabModel.CanClose;
                        //newContentPane.Icon = img.Source;
                    }

                    //When contentPane is closed remove from the associated region
                    newDockableContent.Closed += new EventHandler(newDockableContent_Closed);

                    newDockableContent.HideOnClose = false; 
                    this.hostControl.Items.Add(newDockableContent);
                    newDockableContent.Activate();
                }
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (object oldItem in e.OldItems)
            {
                this.hostControl.Items.Remove(oldItem);
            }
        }
    }

    void newDockableContent_Closed(object sender, EventArgs e)
    {
        var dockableContent = sender as DockableContent;
        if(dockableContent != null)
            if (this.Region.Views.Contains(dockableContent.Content))
            {
                this.Region.Remove(dockableContent.Content);
            }
    }

    private void SynchronizeItems()
    {
        List<object> existingItems = new List<object>();

        // Control must be empty before "Binding" to a region
        foreach (object childItem in this.hostControl.Items)
        {
            existingItems.Add(childItem);
        }

        foreach (object view in this.Region.Views)
        {
            this.hostControl.Items.Add(view);
        }

        foreach (object existingItem in existingItems)
        {
            this.Region.Add(existingItem);
        }
    }


    private void ActiveViews_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (this.updatingActiveViewsInHostControlSelectionChanged)
        {
            // If we are updating the ActiveViews collection in the HostControlSelectionChanged, that 
            // means the user has set the SelectedItem or SelectedItems himself and we don't need to do that here now
            return;
        }

        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            var selectedDockableContent = this.hostControl.SelectedItem as DockableContent;
            if (selectedDockableContent != null
                && selectedDockableContent.Content != null
                && selectedDockableContent.Content != e.NewItems[0]
                && this.Region.ActiveViews.Contains(selectedDockableContent.Content))
            {
                this.Region.Deactivate(selectedDockableContent.Content);
            }

            var _UIElement = e.NewItems[0] as FrameworkElement;
            this.hostControl.SelectedItem = _UIElement.Parent;
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove &&
                 e.OldItems.Contains(this.hostControl.SelectedItem))
        {
            this.hostControl.SelectedItem = null;
        }
    }

    private void HostControlSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        try
        {
            // Record the fact that we are now updating active views in the HostControlSelectionChanged method. 
            // This is needed to prevent the ActiveViews_CollectionChanged() method from firing. 
            this.updatingActiveViewsInHostControlSelectionChanged = true;

            object source;
            source = e.OriginalSource;

            if (source == sender)
            {
                foreach (object item in e.RemovedItems)
                {
                    // check if the view is in both Views and ActiveViews collections (there may be out of sync)
                    var dockableContent = item as DockableContent;
                    if (this.Region.Views.Contains(dockableContent.Content) && this.Region.ActiveViews.Contains(dockableContent.Content))
                    {
                        this.Region.Deactivate(dockableContent.Content);
                    }
                }

                foreach (object item in e.AddedItems)
                {
                    var dockableContent = item as DockableContent;
                    if (this.Region.Views.Contains(dockableContent.Content) && 
                         !this.Region.ActiveViews.Contains(dockableContent.Content))
                    {
                        this.Region.Activate(dockableContent.Content);
                    }
                }
            }
        }
        finally
        {
            this.updatingActiveViewsInHostControlSelectionChanged = false;
        }
    }
}

Code on bootstrapper to configure the Adapter

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    var mappings = base.ConfigureRegionAdapterMappings();
    mappings.RegisterMapping(typeof(AvalonDock.DocumentPane), 
                             this.Container.Resolve<AvalonRegionAdapter>());
    return mappings;
}

Then you need the TabModel and the TabViewModel as fromRaffaeu Bermuda

public sealed class TabModel : DependencyObject
{
   public string Title
   {
       get { return (string)GetValue(TitleProperty); }
       set { SetValue(TitleProperty, value); }
   }

   // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty TitleProperty =
       DependencyProperty.Register("Title", typeof(string), typeof(TabModel));

   public bool CanClose
   {
       get { return (bool)GetValue(CanCloseProperty); }
       set { SetValue(CanCloseProperty, value); }
   }

   // Using a DependencyProperty as the backing store for CanClose.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty CanCloseProperty =
       DependencyProperty.Register("CanClose", typeof(bool), typeof(TabModel));

   public bool IsModified
   {
       get { return (bool)GetValue(IsModifiedProperty); }
       set { SetValue(IsModifiedProperty, value); }
   }

   // Using a DependencyProperty as the backing store for IsModified.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty IsModifiedProperty =
       DependencyProperty.Register("IsModified", typeof(bool), typeof(TabModel));

}

And a TabViewModel acting as a base class:

public class TabViewModel : INotifyPropertyChanged
{
    private TabModel _tabModel;

    public TabModel TabModel
    {
        get { return this._tabModel; }
        set
        {
            this._tabModel = value;
            OnPropertyChanged("TabModel");
        }
    }
    public TabViewModel()
    {
        this.TabModel = new TabModel();
        this.TabModel.CanClose = true;
        this.TabModel.IsModified = false;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

Let me know if you need further help, I will post a blog this in the near future.

南薇 2024-07-29 05:05:00

由于 Avalon DocumentPane 和 DockingPane 都基于 System.Windows.Controls.Primitives.Selector,因此您可以使用 Prism 中的默认 SelectorRegionAdapter。

只需将您的控件基于

<ad:DockableContent x:Class="DesignerWPF.UserControl1"
             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" 
             mc:Ignorable="d" 
             xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
             d:DesignHeight="300" d:DesignWidth="300" Title="dans">
    <Grid>
        <TextBox Text="sdfdf"></TextBox>
    </Grid>
</ad:DockableContent>

主 Shell.xmal 上的 DockableContent,设置可停靠窗格中的区域,

       <ad:DockingManager x:Name="dockManager" Grid.Row="1" Margin="0,4,0,0">
            <ad:ResizingPanel Orientation="Horizontal">
                <ad:DockablePane cal:RegionManager.RegionName="LeftRegion">

                </ad:DockablePane>
                <ad:DocumentPane cal:RegionManager.RegionName="DocumentRegion">

                </ad:DocumentPane>
            </ad:ResizingPanel>
        </ad:DockingManager>

然后当您初始化控件的演示器时,它将显示在扩展坞中。

public class UserTestControl : IModule
    {
        public UserTestControl(IUnityContainer container, IRegionManager regionManager)
        {
            Container = container;
            RegionManager = regionManager;
        }
        public void Initialize()
        {
            var addFundView = Container.Resolve<UserControl1>();
            RegionManager.Regions["LeftRegion"].Add(addFundView);
        }

        public IUnityContainer Container { get; private set; }
        public IRegionManager RegionManager { get; private set; }
    }

Since the Avalon DocumentPane and DockingPane are both based on the System.Windows.Controls.Primitives.Selector you can use the default SelectorRegionAdapter in Prism.

Just base your control on DockableContent

<ad:DockableContent x:Class="DesignerWPF.UserControl1"
             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" 
             mc:Ignorable="d" 
             xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
             d:DesignHeight="300" d:DesignWidth="300" Title="dans">
    <Grid>
        <TextBox Text="sdfdf"></TextBox>
    </Grid>
</ad:DockableContent>

on your main Shell.xmal set the regions in the dockablepane

       <ad:DockingManager x:Name="dockManager" Grid.Row="1" Margin="0,4,0,0">
            <ad:ResizingPanel Orientation="Horizontal">
                <ad:DockablePane cal:RegionManager.RegionName="LeftRegion">

                </ad:DockablePane>
                <ad:DocumentPane cal:RegionManager.RegionName="DocumentRegion">

                </ad:DocumentPane>
            </ad:ResizingPanel>
        </ad:DockingManager>

then when you initialize your presenter for your control it will get displayed in the dock.

public class UserTestControl : IModule
    {
        public UserTestControl(IUnityContainer container, IRegionManager regionManager)
        {
            Container = container;
            RegionManager = regionManager;
        }
        public void Initialize()
        {
            var addFundView = Container.Resolve<UserControl1>();
            RegionManager.Regions["LeftRegion"].Add(addFundView);
        }

        public IUnityContainer Container { get; private set; }
        public IRegionManager RegionManager { get; private set; }
    }
匿名的好友 2024-07-29 05:05:00

我的建议是查看 Prism 源中的 Microsoft.Practices.Composite.Presentation.Regions。 具体来说,查看 ItemsControlRegionAdapter 并将其用作模板。 请记住继承自 RegionAdapterBase<>:

public class ItemsControlRegionAdapter : RegionAdapterBase<ItemsControl>

并覆盖引导程序中的ConfigureRegionAdapterMappings()。 那看起来像:

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    RegionAdapterMappings mappings =  base.ConfigureRegionAdapterMappings();
    mappings.RegisterMapping(typeof(Canvas), Container.Resolve<CanvasRegionAdapter>());
    return mappings;
}

My advice would be to look in Microsoft.Practices.Composite.Presentation.Regions in the Prism source. Specifically, take a look at the ItemsControlRegionAdapter and use it as a template. Remember to inherit from RegionAdapterBase<>:

public class ItemsControlRegionAdapter : RegionAdapterBase<ItemsControl>

and to override ConfigureRegionAdapterMappings() in the bootstrapper. That would look something like:

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    RegionAdapterMappings mappings =  base.ConfigureRegionAdapterMappings();
    mappings.RegisterMapping(typeof(Canvas), Container.Resolve<CanvasRegionAdapter>());
    return mappings;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文