XAF之创建高级Information Panel

来源:互联网 发布:喜马拉雅电台mac版 编辑:程序博客网 时间:2024/06/07 10:23

在XAF的帮助文档中的topic为How to: Create Information Panels(http://documentation.devexpress.com/#Xaf/CustomDocument3309) 讲述了怎样创建InfoPanel,如图:


该主题涉及了自定义模版的较高级的应用,基于FeatureCenter的例子,下面讲述一下怎样创建一个高级InfoPanel,效果如图:


该例子的代码基本来自FeatureCenter,修正了其中的几个bug,根据自己的理解加入了注释。

1.将MainForm模版添加到Model.Win工程下

 %PROGRAMFILES%\DevExpress 2011.2\eXpressApp Framework\Sources\FrameTemplates 下找到MainForm的几个文件,复制到你的Model.Win下。并添加到工程。


2.使用视图设计器打开MainForm,添加SplitContainerControl 

viewSitePanel 添加到SplitContainerControl的Panel1中,然后设置SplitContainerControl的Dock属性为Fill,这部分操作帮助文档讲得很详细,不详述。

这里要注意的是帮助文档上没有说的两点:

1.SplitContainerControl的FixedPanel属性设置为Panel2,这样在缩放窗口时保证Panel2大小固定,更为美观;

2.SplitContainerControl的PanelVisibility属性设置为Panel1,这样通常情况下主窗口仅显示panel1,否则在不使用InfoPanel的窗口中会出现难看的空白分割线


3.继承一个IFrameTemplate接口,用于操作SplitContainerControl

using DevExpress.ExpressApp.Templates;//... public interface IInfoPanelTemplateWin : IFrameTemplate {            DevExpress.XtraEditors.SplitContainerControl SplitContainer { get; }}

若自定义模版添加了其他控件,也需要定义一个类似接口获取这些新控件的引用。

在我们添加的MainForm中添加代码,使MainForm继承实现IInfoPanelTemplateWin接口

public partial class MainForm : MainFormTemplateBase, IDockManagerHolder, ISupportMdiContainer,     ISupportClassicToRibbonTransform, IInfoPanelTemplateWin{    //...     public DevExpress.XtraEditors.SplitContainerControl SplitContainer {        get { return splitContainerControl1; }    }}
为了支持MDI,还要修改Mainform的UpdateMdiModeDependentProperties方法:

public partial class MainForm : MainFormTemplateBase, IDockManagerHolder, ISupportMdiContainer,     ISupportClassicToRibbonTransform, IInfoPanelTemplateWin {    //...     protected override void UpdateMdiModeDependentProperties() {        //viewSitePanel.Visible = !isMdi;         splitContainerControl1.Visible = !isMdi;        //...     }}
4.修改Program.cs,使XAF使用自定义的模版而不是默认Mainform模版

static void Main()        {//...            winApplication.CreateCustomTemplate += new EventHandler<CreateCustomTemplateEventArgs>(xafApplication_CreateCustomTemplate);//...        }        static void xafApplication_CreateCustomTemplate(object sender, CreateCustomTemplateEventArgs e)        {            if (e.Context.Name == TemplateContext.ApplicationWindow)            {                e.Template = new DevExpress.ExpressApp.Win.CustomTemplates.MainForm();            }        }

5.继承CustomizeTemplateViewControllerBase,实现其虚拟方法

  • AddControlsToTemplateCore(TemplateType template)
    当Controller激活时,初始化控件,并添加到Template
  • RemoveControlsFromTemplateCore(TemplateType template)
    当Controller禁用时,删除控件
  • UpdateControls(View view)
    当View改变时,更新控件
  • UpdateControls(object currentObject)
     View的当前object改变时,更新控件

下面直接给出代码,查看代码及注释应该能理解,稍做修改就能用于自己的场景。

--------------------------------------InfoPanelsViewControllerBase<TemplateType>-------------------------------------------------------

/// <summary>    /// InfoPanelsViewControllerBase类继承自CustomizeTemplateViewControllerBase    /// 并实现了其UpdateControls(View view),UpdateControls(object currentObject)方法    /// 其他方法和Control相关,故在InfoPanelsViewController中实现    /// 本基类放在Module中,故只实现了对象相关的逻辑:代表InfoPanel的relatedViewFrame和    /// PopupWindowShowAction按钮逻辑及显示文本的逻辑。    /// GetInfoText()获取要显示的文本    /// CreateRelatedViewControl()创建InfoPanel的Frame    /// </summary>    /// <typeparam name="TemplateType"></typeparam>    public abstract class InfoPanelsViewControllerBase<TemplateType> : CustomizeTemplateViewControllerBase<TemplateType> where TemplateType : IFrameTemplate    {        private PopupWindowShowAction action;        private Frame relatedViewFrame;        //获取ListView的当前TestObject的Name        private string GetInfoText()        {            string currentObjectRelatedInfo;            if (View is ListView && View.CurrentObject == null)            {                currentObjectRelatedInfo = "Empty";            }            else            {                currentObjectRelatedInfo =  ((TestObject)View.CurrentObject).Name;            }            return currentObjectRelatedInfo;        }        //点击My Action弹出DetailView        private void action_CustomizePopupWindowParams(object sender, CustomizePopupWindowParamsEventArgs e)        {            IObjectSpace objectSpace = Application.CreateObjectSpace();            DetailView detailView = Application.CreateDetailView(objectSpace, objectSpace.GetObject(View.CurrentObject));            e.View = detailView;            e.Context = TemplateContext.PopupWindow;        }        private void view_ControlsCreated(object sender, EventArgs e)        {            ((View)sender).ControlsCreated -= new EventHandler(view_ControlsCreated);            if (relatedViewFrame != null && relatedViewFrame.Template is ISupportStoreSettings)            {                ISupportStoreSettings storeSettings = (ISupportStoreSettings)relatedViewFrame.Template;                storeSettings.SetSettings(Application.GetTemplateCustomizationModel(relatedViewFrame.Template));                storeSettings.ReloadSettings();            }        }        private void View_ModelSaved(object sender, EventArgs e)        {            if (relatedViewFrame != null && relatedViewFrame.Template is ISupportStoreSettings)            {                ((ISupportStoreSettings)relatedViewFrame.Template).SaveSettings();            }        }        protected abstract void SetInfoTextToControls(string text);        //创建Info Panel的Detail视图        protected object CreateRelatedViewControl()        {            if (relatedViewFrame == null)            {                #region 这部分代码展示了Frame和Template,ObjectSpace和View的关系                //为Frame赋值后必须调用CreateTemplate方法创建Template                relatedViewFrame = Application.CreateFrame(TemplateContext.NestedFrame);                relatedViewFrame.CreateTemplate();                IObjectSpace objectSpace = Application.CreateObjectSpace();                DetailView view = Application.CreateDetailView(objectSpace, "TestObject_DetailView_Copy", false, objectSpace.GetObject(View.CurrentObject));                view.ControlsCreated += new EventHandler(view_ControlsCreated);                view.AllowEdit["Demo"] = false;                relatedViewFrame.SetView(view);                #endregion            }            else            {                if (NeedRecreateRelatedViewFrameTemplate)                {                    relatedViewFrame.View.BreakLinksToControls();                    relatedViewFrame.SetTemplate(null);                    relatedViewFrame.CreateTemplate();                }            }            return relatedViewFrame.Template;        }        protected override void UpdateControls(View view)        {            SetInfoTextToControls(GetInfoText());        }        protected override void UpdateControls(object currentObject)        {            SetInfoTextToControls(GetInfoText());            if (relatedViewFrame != null)            {                //若不刷新ObjectSpace,则无法及时显示修改的记录                relatedViewFrame.View.ObjectSpace.Refresh();                relatedViewFrame.View.CurrentObject = currentObject == null ? null : relatedViewFrame.View.ObjectSpace.GetObject(currentObject);            }        }        protected override void OnActivated()        {            base.OnActivated();            View.ModelSaved += new EventHandler(View_ModelSaved);        }        protected override void OnDeactivated()        {            base.OnDeactivated();            View.ModelSaved -= new EventHandler(View_ModelSaved);        }        public InfoPanelsViewControllerBase()        {            TargetObjectType = typeof(TestObject);            //该Action的Category为ContextActions,该ActionContainer将在InfoPanelsViewController创建            action = new PopupWindowShowAction(this, "ContextAction", "ContextActions");            action.Caption = "My Action";            action.SelectionDependencyType = SelectionDependencyType.RequireSingleObject;            action.CustomizePopupWindowParams += new CustomizePopupWindowParamsEventHandler(action_CustomizePopupWindowParams);            RegisterActions(action);        }        protected virtual bool NeedRecreateRelatedViewFrameTemplate        {            get { return false; }        }    }


--------------------------------------InfoPanelsViewControllerBase<TemplateType>-------------------------------------------------------

--------------------------------------InfoPanelsViewController-------------------------------------------------------

/// <summary>    /// InfoPanelsViewController放置于Module.Win中,继承了InfoPanelsViewControllerBase    /// 实现控件相关逻辑;实现了AddControlsToTemplateCore(IInfoPanelTemplateWin template)    /// 和RemoveControlsFromTemplateCore(IInfoPanelTemplateWin template)    /// 将文本,按钮,relatedView放置于GroupControl中分组显示    /// </summary>    public class InfoPanelsViewController : InfoPanelsViewControllerBase<IInfoPanelTemplateWin>    {        #region 创建模版上要显示的控件        private GroupControl textPanel;        private GroupControl actionConainersPanel;        private GroupControl relatedViewPanel;        private LabelControl literal;        //若SplitContainerControl的Panel2中不含控件,则隐藏Panel2        //由于自定义MainForm的Template后,所有MainForm都使用该模版        //若不控制SplitContainerControl的显示/隐藏,则会影响其他不需要多面板的        //Form,导致其他主Form也出现SplitContainerControl的分割线,使画面很难看        private void UpdateInfoPanelVisibility(SplitContainerControl splitContainer)        {            splitContainer.PanelVisibility = splitContainer.Panel2.Controls.Count > 0 ? SplitPanelVisibility.Both : SplitPanelVisibility.Panel1;        }        private void EnsureControls()        {            if (textPanel == null)            {                CreateTextPanel();                CreateActionContainerPanel();                CreateRelatedViewPanel();            }        }        private void CreateRelatedViewPanel()        {            relatedViewPanel = CreateGroupControl("View Panel");            System.Windows.Forms.Control viewControl = (System.Windows.Forms.Control)CreateRelatedViewControl();            viewControl.Dock = System.Windows.Forms.DockStyle.Top;            relatedViewPanel.Controls.Add(viewControl);        }        //在代码中创建一个ActionContainer        private void CreateActionContainerPanel()        {            actionConainersPanel = CreateGroupControl("Action Panel");            ButtonsContainer actionContainer = new ButtonsContainer();            actionContainer.Dock = System.Windows.Forms.DockStyle.Top;            actionContainer.ContainerId = "ContextActions";            actionConainersPanel.Controls.Add(actionContainer);            IDynamicContainersTemplate template = Frame.Template as IDynamicContainersTemplate;            if (template != null)            {                template.RegisterActionContainers(new[] { actionContainer });            }        }        private void CreateTextPanel()        {            textPanel = CreateGroupControl("Text Panel");            textPanel.Padding = new System.Windows.Forms.Padding(6);            literal = new LabelControl();            literal.AllowHtmlString = true;            literal.Dock = System.Windows.Forms.DockStyle.Top;            literal.AutoSizeMode = LabelAutoSizeMode.Vertical;            textPanel.Controls.Add(literal);        }        private GroupControl CreateGroupControl(string caption)        {            GroupControl panel = new GroupControl();            panel.AutoSize = true;            panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;            panel.Dock = System.Windows.Forms.DockStyle.Top;            panel.Text = caption;            return panel;        }        protected override void SetInfoTextToControls(string text)        {            if (literal != null)            {                literal.Text = text;            }        }        #endregion        #region 这两个方法继承自CustomizeTemplateViewControllerBase,在Controller激活/禁用时添加/删除控件        protected override void AddControlsToTemplateCore(IInfoPanelTemplateWin template)        {            EnsureControls();            template.SplitContainer.Panel2.Controls.Add(relatedViewPanel);            template.SplitContainer.Panel2.Controls.Add(actionConainersPanel);            template.SplitContainer.Panel2.Controls.Add(textPanel);            UpdateInfoPanelVisibility(template.SplitContainer);        }        protected override void RemoveControlsFromTemplateCore(IInfoPanelTemplateWin template)        {            template.SplitContainer.Panel2.Controls.Remove(relatedViewPanel);            template.SplitContainer.Panel2.Controls.Remove(actionConainersPanel);            template.SplitContainer.Panel2.Controls.Remove(textPanel);            UpdateInfoPanelVisibility(template.SplitContainer);            textPanel = null;            actionConainersPanel = null;            literal = null;        }        #endregion        public InfoPanelsViewController():base()        {            DevExpress.ExpressApp.Actions.SimpleAction showHideAction =                new DevExpress.ExpressApp.Actions.SimpleAction(this, "ShowHideInfoPanel", DevExpress.Persistent.Base.PredefinedCategory.View);            showHideAction.Execute += new DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(showHideAction_Execute);        }        void showHideAction_Execute(object sender, DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs e)        {            SplitContainerControl splitContainer = ((IInfoPanelTemplateWin)Frame.Template).SplitContainer;            splitContainer.PanelVisibility = splitContainer.PanelVisibility == DevExpress.XtraEditors.SplitPanelVisibility.Both ? DevExpress.XtraEditors.SplitPanelVisibility.Panel1 : DevExpress.XtraEditors.SplitPanelVisibility.Both;        }    }


--------------------------------------InfoPanelsViewController-------------------------------------------------------



原创粉丝点击