/// <summary> /// 更新控件,组件的可视状态 /// 通过获取组件的IShellControlDev接口,调用UpdateView方法 /// </summary> /// <param name="components"></param> public void UpdateView(IComponent[] components) { for (int i = 0; i < components.Length; i++) { IShellControlDev shellControlDev = components[i] as IShellControlDev; if (shellControlDev == null) { Debug.WriteLine("component 没有实现 IShellControlDev 接口"); continue; } //这里try catch目前是为了兼容设置字体时可能出现的异常 //见 ElementFont 中的说明 try { shellControlDev.UpdateView(); } catch (Exception ex) { Debug.Assert(false, "shellControlDev.UpdateView()失败", ex.Message); //UpdateView不成功,根据控件状态同步实体对象 //暂时不更新属性行中的显示了 //对于主要要解决的字体设置的问题,update时字体对象会clone一个新的 //这里调e.Row.UpdateProperty是没用的,因为行上还是旧的对象,重新设置新的对象也比较麻烦,要考虑多选的问题 //字体出错的问题比较少,这里只要对象同步了也没有大问题,暂不过多处理了 shellControlDev.UpdateEntity(); PropertyGridDataErrorView formDataError = new PropertyGridDataErrorView(ex.Message); formDataError.ShowDialog(); } } }
/// <summary> /// 此事件在关闭事务后发生 /// 在设计器中操作对象后引发,通过属性面板更新对象不会引发此事件 /// 注意:设计器中,添加组件不会进这个事件,只有变更组件,删除组件才会进 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Host_TransactionClosed(object sender, DesignerTransactionCloseEventArgs e) { if (!e.LastTransaction) { return; } #region 提交可撤销的工作单元集合 //提交可撤销的工作单元集合(如果需要),提交之后清空临时可撤销工作单元集合 if (this._undoUnitList.Count > 0) { this._undoUnitList.Clearup(); this._undoEngine.AddUndoUnit(_undoUnitList); this._undoUnitList.Clear(); } #endregion #region 如果执行了添加或删除组件操作,更新属性面板上面下拉框 //如果执行了添加或删除组件操作,更新属性面板上面下拉框 //放在 TransactionClosed 事件里而不是 Add 或 Remove 事件里,是因为在批量剪切粘贴时 //Add 或 Remove 会多次执行,而 TransactionClosed 只会在完成操作时触发 //需判断是否是撤销重做引擎引发的事件,如果是,不在这里更新,在撤销重做引擎的OnTransactionClosed事件中更新 if (ComponentListChanged && !_undoEngine.Working) { UpdatePropertyPadComponentList(); } #endregion #region 步组件属性到实体对象 //这段代码要处理的典型情况是粘贴组件时,同步组件实体对象的坐标属性值 //在 ComponentChanged 事件中同步还不行,ComponentChanged事件中跟不到组件新的位置坐标 //只能跟到组件左上角坐标为15,15的时候 //估计是设计器在使用复制的组件初始化新组件后,不再引发ComponentChanged事件 //初始化完毕后进TransactionClosed ICollection selectedComponents = this._selectionService.GetSelectedComponents(); if (selectedComponents != null) { //ICollection不支持下标访问 object[] selArray = new object[selectedComponents.Count]; selectedComponents.CopyTo(selArray, 0); for (int i = 0; i < selectedComponents.Count; i++) { IShellControlDev shellControlDev = selArray[i] as IShellControlDev; if (shellControlDev != null) { shellControlDev.UpdateEntity(); } } } #endregion }
/// <summary> /// 根据实体对象在窗体根窗口中创建对象 /// 公开方法是撤销重做引擎需要用到 /// 需要public出来给撤销重做引擎调用 /// </summary> /// <param name="element"></param> public void CreateControl(UIElement element) { //Control control = ControlFactory.InitControl(element, this._designSurface); IFormElementEntityDev entityDev = element as IFormElementEntityDev; if (entityDev == null) { throw new NotImplementedException(); } //TODO:考虑在IDE中继承DesignSurface,并重写CreateControl,在调用基类的CreateControl后,直接把Entity对象放进去 Control control = this._designSurface.CreateControl(entityDev.DesignerControlType, element.Size, element.Location); IShellControlDev shellControlDev = control as IShellControlDev; element.HostFormEntity = this._windowEntity; shellControlDev.Entity = element; Debug.WriteLine("挂上Entity : " + element.GetType().Name); shellControlDev.UpdateView(); //这种情况发生在撤销重做引擎中 //初始化的时候,element是在formEntity中的,但是在撤销时,肯定不在,已经被移除了 //if (!_formEntity.Elements.Contains(element)) //{ // _formEntity.Elements.Add(element); //} }
/// <summary> /// 在组件已移除时发生 /// 注意:在 DesignSurface Dispose 时,所有组件都会触发此事件 /// 所以在 DesignSurface 的 Unloading 事件里注销了此事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void componentChangeService_ComponentRemoved(object sender, ComponentEventArgs e) { if (_designSurfaceUnloading) { return; } Control control = e.Component as Control; IShellControlDev shellControlDev = control as IShellControlDev; //将关联的实体对象从formEntity中删除 this._windowEntity.Elements.Remove((UIElement)shellControlDev.Entity); ComponentListChanged = true; #region 封装可撤销的工作单元 //这里也要考虑同时删除多个组件的可能,比如粘贴操作,需要把同时添加的多个组件封装为一个事务 if (!_undoEngine.Working) { SEUndoUnitFormDesigner undoUnit = new SEUndoUnitFormDesigner("ComponentRemoved"); undoUnit.Type = SEUndoUnitFormDesigner.UndoUnitType.ComponentRemoved; undoUnit.Components = e.Component as IComponent; undoUnit.Entity = shellControlDev.Entity; this._undoUnitList.Add(undoUnit); } #endregion Debug.WriteLine("删除了窗体对象:" + shellControlDev.Entity.Code); Debug.WriteLine("当前窗体元素个数:" + this._windowEntity.Elements.Count); }
private bool formCollectionEditor_OnEdit(object obj, FormCollectionEditor.CollectionEditorEventArgs e, out object oldValue) { ICloneable clone = obj as ICloneable; oldValue = obj; if (clone != null) { oldValue = clone.Clone(); } IShellControlDev shellControlDev = this.Control as IShellControlDev; FormElementDataListEntityDev formElementDataListEntityDev = shellControlDev.Entity as FormElementDataListEntityDev; using (FormSEPaginationDataGridViewDevColumnAdd formFormElementAdd_DataColumn = new FormSEPaginationDataGridViewDevColumnAdd(formElementDataListEntityDev)) { formFormElementAdd_DataColumn.FormElementDataColumnEntity = (FormElementDataListTextBoxColumnEntityDev)obj; formFormElementAdd_DataColumn.FormEntity = (FormEntityDev)formElementDataListEntityDev.HostFormEntity; formFormElementAdd_DataColumn.EditCollection = e.EditCollection; if (formFormElementAdd_DataColumn.ShowDialog() == DialogResult.OK) { return(true); } else { return(false); } } }
private void DataRule(object sender, EventArgs args) { IShellControlDev shellControlDev = this.Control as IShellControlDev; FormSEComboBoxExDevDataRule formSEComboBoxExDevDataRule = new FormSEComboBoxExDevDataRule((FormElementComboBoxEntityDev)shellControlDev.Entity); formSEComboBoxExDevDataRule.ShowDialog(); }
private void DataRule(object sender, EventArgs args) { IShellControlDev shellControlDev = this.Control as IShellControlDev; using (FormSETextBoxExDevDataRule formSETextBoxExDevDataRule = new FormSETextBoxExDevDataRule((FormElementTextBoxEntityDev)shellControlDev.Entity)) { formSETextBoxExDevDataRule.ShowDialog(); } }
//private string GetObjectSiteName(object o) //{ // if (o != null) // { // IComponent component = o as IComponent; // if (component != null) // { // ISite site = component.Site; // if (site != null) // { // return site.Name; // } // } // return o.GetType().ToString(); // } // return String.Empty; //} /// <summary> /// 获取控件的显示名(所关联对象的Code) /// </summary> /// <param name="o"></param> /// <returns></returns> private string GetObjectSiteName(object o) { if (o != null) { IShellControlDev component = o as IShellControlDev; if (component != null) { return(component.GetCode()); } return(o.GetType().ToString()); } return(String.Empty); }
/// <summary> /// 如果当前属性面板窗体有效(可见状态) /// 将实体对象提取出来,然后设置到属性网格中 /// </summary> private void UpdateSelectedObjectIfActive() { //如果窗体不可见,不更新属性网格 if (!this.Visible) { return; } //加载当前可用的设计器谓词 //先加载设计器谓词,避免先显示了属性行再显示谓词面板造成属性行部分滚动条闪动 if (this.Host != null) { IMenuCommandService menuCommandService = this.Host.GetService(typeof(IMenuCommandService)) as IMenuCommandService; Debug.Assert(menuCommandService != null, "menuCommandService 为 null"); if (menuCommandService != null) { this.PropertyGrid.Verbs = menuCommandService.Verbs; } } if (SelectedObjects != null) { EntityBase[] entity = new EntityBase[SelectedObjects.Length]; object[] selArray = new object[SelectedObjects.Length]; SelectedObjects.CopyTo(selArray, 0); for (int i = 0; i < SelectedObjects.Length; i++) { IShellControlDev shellControlDev = selArray[i] as IShellControlDev; //entity[i] = shellControlDev.GetEntity(); entity[i] = shellControlDev.Entity; } SetDesignableObjects(entity); } else { IShellControlDev shellControlDev = SelectedObject as IShellControlDev; if (shellControlDev != null) { //SetDesignableObject(shellControlDev.GetEntity()); SetDesignableObjects(new object[] { shellControlDev.Entity }); } else { SetDesignableObjects(null); } } }
private void AddColumn(object sender, EventArgs args) { IShellControlDev shellControlDev = this.Control as IShellControlDev; FormElementDataListEntityDev formElementDataListEntityDev = (FormElementDataListEntityDev)shellControlDev.Entity; using (FormSEPaginationDataGridViewDevColumnAdd formSEPaginationDataGridViewDevColumnAdd = new FormSEPaginationDataGridViewDevColumnAdd(formElementDataListEntityDev)) { formSEPaginationDataGridViewDevColumnAdd.FormEntity = (FormEntityDev)formElementDataListEntityDev.HostFormEntity; formSEPaginationDataGridViewDevColumnAdd.ShellControlDev = shellControlDev; formSEPaginationDataGridViewDevColumnAdd.ShowDialog(); } }
private void EditColumns(object sender, EventArgs args) { IShellControlDev shellControlDev = this.Control as IShellControlDev; FormElementDataListEntityDev formElementDataListEntityDev = shellControlDev.Entity as FormElementDataListEntityDev; using (FormCollectionEditor formCollectionEditor = new FormCollectionEditor(formElementDataListEntityDev.DataColumns, true)) { formCollectionEditor.Title = Language.Current.SEPaginationDataGridViewDev_Verb_FormCollectionEditorTitle; formCollectionEditor.OnAdd += new FormCollectionEditor.CollectionEditorAddEventHandler(formCollectionEditor_OnAdd); formCollectionEditor.OnEdit += new FormCollectionEditor.CollectionEditorEditEventHandler(formCollectionEditor_OnEdit); if (formCollectionEditor.ShowDialog() == DialogResult.OK) { #region 处理可撤销的工作单元 if (formCollectionEditor.SupportCancel) { formCollectionEditor.UndoTransaction.SetName(Language.Current.SEPaginationDataGridViewDev_EditColumns_UndoTransaction_Name); //在可撤销单元被撤销或重做时,刷新设计器中呈现的列 formCollectionEditor.UndoTransaction.Action = new Action <SEUndoUnitAbstract, SEUndoEngine.Type>( delegate(SEUndoUnitAbstract undoUnit, SEUndoEngine.Type type) { SEUndoEngineFormDesigner undoEngine = undoUnit.UndoEngine as SEUndoEngineFormDesigner; undoEngine.UpdateView(shellControlDev.Entity); undoEngine.UpdatePropertyGrid(false); }); _windowDesignService.AddUndoUnit(formCollectionEditor.UndoTransaction); } #endregion shellControlDev.UpdateView(); _windowDesignService.MakeDirty(); } } }
private void FormEvents_Load(object sender, EventArgs e) { if (FormHostingContainer.Instance.ActiveHosting == null) { return; } if (FormHostingContainer.Instance.ActiveHosting.SelectionService.PrimarySelection == null) { return; } object primarySelection = FormHostingContainer.Instance.ActiveHosting.SelectionService.PrimarySelection; IShellControlDev shellControlDev = primarySelection as IShellControlDev; if (shellControlDev == null) { throw new NotImplementedException(); } this._userControlEvent = new UserControlEvent(shellControlDev.Entity); this._userControlEvent.FormEntity = FormHostingContainer.Instance.ActiveFormEntity; this._userControlEvent.Dock = DockStyle.Fill; this._userControlEvent.OnEdited += new UserControlEvent.OnEditedEventHandler(_userControlEvent_OnAfterEdit); this.Controls.Add(this._userControlEvent); }
private bool formCollectionEditor_OnAdd(FormCollectionEditor.CollectionEditorEventArgs e, out object addValue) { IShellControlDev shellControlDev = this.Control as IShellControlDev; FormElementDataListEntityDev formElementDataListEntityDev = shellControlDev.Entity as FormElementDataListEntityDev; using (FormSEPaginationDataGridViewDevColumnAdd formFormElementAdd_DataColumn = new FormSEPaginationDataGridViewDevColumnAdd(formElementDataListEntityDev)) { formFormElementAdd_DataColumn.FormEntity = (FormEntityDev)formElementDataListEntityDev.HostFormEntity; formFormElementAdd_DataColumn.EditCollection = e.EditCollection; if (formFormElementAdd_DataColumn.ShowDialog() == DialogResult.OK) { addValue = formFormElementAdd_DataColumn.FormElementDataColumnEntity; return(true); } else { addValue = null; return(false); } } }
private void UpdateSelection(FormDesignSurfaceHosting hosting) { if (hosting == null || hosting.SelectionService == null) { this.Entity = null; return; } ICollection selection = hosting.SelectionService.GetSelectedComponents(); if (selection != null && selection.Count == 1) { object[] selArray = new object[selection.Count]; selection.CopyTo(selArray, 0); IShellControlDev shellControlDev = selArray[0] as IShellControlDev; if (shellControlDev != null) { this.Entity = shellControlDev.Entity; } } else { this.Entity = null; } }
/// <summary> /// 为控件创建并绑定实体对象 /// </summary> /// <param name="shellControlDev"></param> private void CreateEntity(IShellControlDev shellControlDev) { Type type = shellControlDev.GetType(); object [] attributes = type.GetCustomAttributes(typeof(RuntimeControlDesignSupportAttribute), false); if (attributes.Length == 1) { RuntimeControlDesignSupportAttribute attr = (RuntimeControlDesignSupportAttribute)attributes[0]; UIElement entity = Activator.CreateInstance(attr.EntityType) as UIElement; if (entity == null) { Debug.Assert(false, "无法创建实体对象,RuntimeControlDesignSupportAttribute.EntityType 不是 UIElement"); return; } entity.Code = _windowEntity.CreationElementCode(attr.CodeCreationPrefix); entity.Name = entity.Code; shellControlDev.InitializationEntity(entity); shellControlDev.Entity = entity; } else { Debug.Assert(false, "无法创建实体对象,没有找到 RuntimeControlDesignSupportAttribute"); } }
/// <summary> /// 在组件属性发生更改时发生 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void componentChangeService_ComponentChanged(object sender, ComponentChangedEventArgs e) { if (_designSurfaceUnloading) { return; } if (this.HostingContainer.PropertyChanging) { return; } //同步到控件所关联的Entity中 Control control = e.Component as Control; if (control == null) { return; } IShellControlDev shellControlDev = control as IShellControlDev; if (shellControlDev == null) { throw new NotImplementedException(); } if (shellControlDev.Entity == null) { return; } if (shellControlDev.ViewUpdating) { return; } this._componentChanging = true; //在ComponentAdded之后,ComponentChanged会进来多次 //虽然ComponentAdded事件中已经处理了控件的显示文本,但是最后一次进入ComponentChanged时 //其显示文本又会是类型名开头的文本,不知道为什么,看调用堆栈是从Toolbox过来的 //这里做个判断,若不同强制其更新使用Entity中的文本 if (control.Text != shellControlDev.GetText()) { control.Text = shellControlDev.GetText(); } //start:这两行代码拿到Host_TransactionClosed里还不行 //添加控件后触发Host_TransactionClosed事件中, //this._selectionService.GetSelectedComponents()取下来的不是添加的那个控件,而是根容器窗体, //或者说添加控件的父控件(暂没实现多级,这一说法未测,目前的情况就是窗体) //而如果是改变控件的ZOrder,进到这里时,取到的 e.Component是被改变的控件的父控件 //需要到Host_TransactionClosed事件中,去同步实体对象以更新ZOrder //注意的是,撤销重做操作均不引发ComponentChanged和Host_TransactionClosed事件,需在Undo,Redo操作中同步ZOrder shellControlDev.UpdateEntity(); //通知属性网格属性已更改 //不能在这里判断_componentChanging,因为更新属性行上的属性值还是必须的 //需要在属性值更新后引发的PropertyGrid_PropertyChanged事件中判断 this.HostingContainer.UpdatePropertyGrid(); //end #region 封装可撤销的工作单元 if (!_undoEngine.Working)// && !e.NewValue.Equals(e.OldValue)) { if (e.Member.Name != "Controls") { SEUndoUnitFormDesigner undoUnit = new SEUndoUnitFormDesigner(e.Member.Name); undoUnit.Type = SEUndoUnitFormDesigner.UndoUnitType.ComponentChanged; undoUnit.Components = e.Component as IComponent; undoUnit.Entity = shellControlDev.Entity; undoUnit.Members.Add(e.Member.Name, e.OldValue, e.NewValue); this._undoUnitList.Add(undoUnit); } } #endregion this._componentChanging = false; MakeDirty(); Debug.WriteLine("对象属性已更新:" + shellControlDev.Entity.Code); }
/// <summary> /// 在组件已添加时发生 /// 此事件在 FormFormDesinger_Load 执行 InitialseFormElementsComponent() 后挂接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void componentChangeService_ComponentAdded(object sender, ComponentEventArgs e) { //这个事件里的代码主要是为添加的组件添加实体对象 Control control = e.Component as Control; //如果是窗体,返回 //这里不能和_rootComponentForm比较,_designSurface.CreateRootComponent执行后结果才会赋值到_rootComponentForm //另外窗体所对应的实体对象不在这里设置 if (control is IWindowDesignerRootComponent) { return; } //为新增的组件绑定一个实体对象 IShellControlDev shellControlDev = control as IShellControlDev; if (shellControlDev.Entity == null) { //shellControlDev.CreateEntity(this._formEntity); CreateEntity(shellControlDev); _windowEntity.Elements.Add((UIElement)shellControlDev.Entity); } else { if (this.WindowEntity.Elements.Contains(shellControlDev.Entity as UIElement) == false) { UIElement formElementEntity = shellControlDev.Entity.Clone() as UIElement; //要先清除,不能直接赋值 //因为IShellControlDev.Entity的set中有逻辑处理.会把set过来的Entity对象放到原Entity对象一样的FormEntity中 shellControlDev.ClearEntity(); shellControlDev.Entity = formElementEntity; //添加实体对象到当前FormEntity.Elements中 this.WindowEntity.Elements.Add(formElementEntity); } } shellControlDev.UpdateView(); ComponentListChanged = true; #region 封装可撤销的工作单元 //这里也要考虑同时添加多个组件的可能,比如粘贴操作,需要把同时添加的多个组件封装为一个事务 if (!_undoEngine.Working) { SEUndoUnitFormDesigner undoUnit = new SEUndoUnitFormDesigner("ComponentAdded"); undoUnit.Type = SEUndoUnitFormDesigner.UndoUnitType.ComponentAdded; undoUnit.Components = e.Component as IComponent; this._undoUnitList.Add(undoUnit); } #endregion Debug.WriteLine("增加了窗体对象:" + shellControlDev.Entity.Code + "( " + shellControlDev.Entity.GetType().Name + " )"); Debug.WriteLine("当前窗体元素个数:" + this._windowEntity.Elements.Count); }
private void ComboBoxDrawItem(object sender, DrawItemEventArgs dea) { if (dea.Index < 0 || dea.Index >= this.comboBoxFormElementList.Items.Count) { return; } Graphics g = dea.Graphics; Brush stringColor = SystemBrushes.ControlText; if ((dea.State & DrawItemState.Selected) == DrawItemState.Selected) { if ((dea.State & DrawItemState.Focus) == DrawItemState.Focus) { g.FillRectangle(SystemBrushes.Highlight, dea.Bounds); stringColor = SystemBrushes.HighlightText; } else { g.FillRectangle(SystemBrushes.Window, dea.Bounds); } } else { g.FillRectangle(SystemBrushes.Window, dea.Bounds); } object item = this.comboBoxFormElementList.Items[dea.Index]; int xPos = dea.Bounds.X; /* * if (item is IComponent) * { * ISite site = ((IComponent)item).Site; * if (site != null) * { * string name = site.Name; * using (Font f = new Font(this.comboBoxFormElementList.Font, FontStyle.Bold)) * { * g.DrawString(name, f, stringColor, xPos, dea.Bounds.Y); * xPos += (int)g.MeasureString(name + "-", f).Width; * } * } * } */ string typeString = String.Empty; if (item is IShellControlDev) { IShellControlDev site = (IShellControlDev)item; if (site != null) { string name = site.GetCode(); using (Font f = new Font(this.comboBoxFormElementList.Font, FontStyle.Bold)) { g.DrawString(name, f, stringColor, xPos, dea.Bounds.Y); xPos += (int)g.MeasureString(name + "-", f).Width; } typeString = site.GetControlTypeName(); } } // string typeString = item.GetType().ToString(); g.DrawString(typeString, this.comboBoxFormElementList.Font, stringColor, xPos, dea.Bounds.Y); }