Fragensteller
Columns von ListView in UserControl werden im Designer nicht korrekt upgedated.

Allgemeine Diskussion
-
A:
Wenn ich zu einer WindowsForm ein ListView, View: Details hinzufüge und dann im Designer die Columns Eigenschaft bearbeite, werden alle Columns immer korrekt und sofort im Designer upgedated.
B:
Wenn ich in einem UserControl ein ListView, View: Details hinzufüge und dann im Designer die Columns Eigenschaft bearbeite, werden beim Ersten Öffnen des CollectionEditors auch alle Columns korrekt und sofort im Designer upgedated. Schließe ich aber den CollectionEditor und öffne ihn wieder, werden nur neu hinzugefügte Columns korrekt, sofort upgedated, die "alten", schon vorher bestehenden Columns aber nicht. Das fäält insbesondere beim Löschen alter Columns auf, siehe Bild. Zumindest werden aber die Columns dann beim Schließen des CollectionEditors upgedated.
public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); this.listView1.View = View.Details; } public ListView.ColumnHeaderCollection Columns { get { return listView1.Columns; } } }
C:
Bei einer Implementierung mit einem IComponentChangeService werden beim Ersten Bearbeiten der Columns alle Columns richtig hizugefügt, bzw. entfernt. Bei weiteren Bearbeitungen mittels des Editors jedoch auch nicht. Außerdem wird die Ansicht auch nach dem Schließen des Editors nicht korrekt aktualisiert. Der ChangeService feuert keine Events für "alte", bestehende Columns.
Konkret geht es darum, in einem UserControl die Columns zweier ListViews synchron zu halten, siehe: https://social.msdn.microsoft.com/Forums/windows/en-US/64d05c81-3200-4092-80f7-b04f7a8a2ee8/vs-2015-community-why-does-the-property-for-a-collection-that-derives-from-ilist-nongeneric-not?forum=winforms
Meine Frage, wie kann man das Lösen - ich habe Component development keine Ahnung, so weiß ich hier keinen Rat, weiß auch nicht, ob ein ChangeService hier überhaupt die richtige Wahl ist.
[Ein UserControl, Name SelectionList, Name lvMain, ein ListView, Viel.Details, Reference zu System.Design.dll]
public partial class SelectionList : UserControl { private IComponentChangeService m_changeService; // This override allows the control to register event handlers for IComponentChangeService events // at the time the control is sited, which happens only in design mode. public override ISite Site { get { return base.Site; } set { // Clear any component change event handlers. ClearChangeNotifications(); // Set the new Site value. base.Site = value; m_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); // Register event handlers for component change events. RegisterChangeNotifications(); } } private void ClearChangeNotifications() { // The m_changeService value is null when not in design mode, // as the IComponentChangeService is only available at design time. m_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); // Clear our the component change events to prepare for re-siting. if (m_changeService != null) { m_changeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged); m_changeService.ComponentChanging -= new ComponentChangingEventHandler(OnComponentChanging); m_changeService.ComponentAdded -= new ComponentEventHandler(OnComponentAdded); m_changeService.ComponentAdding -= new ComponentEventHandler(OnComponentAdding); m_changeService.ComponentRemoved -= new ComponentEventHandler(OnComponentRemoved); m_changeService.ComponentRemoving -= new ComponentEventHandler(OnComponentRemoving); m_changeService.ComponentRename -= new ComponentRenameEventHandler(OnComponentRename); } } private void RegisterChangeNotifications() { // Register the event handlers for the IComponentChangeService events if (m_changeService != null) { m_changeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged); m_changeService.ComponentChanging += new ComponentChangingEventHandler(OnComponentChanging); m_changeService.ComponentAdded += new ComponentEventHandler(OnComponentAdded); m_changeService.ComponentAdding += new ComponentEventHandler(OnComponentAdding); m_changeService.ComponentRemoved += new ComponentEventHandler(OnComponentRemoved); m_changeService.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving); m_changeService.ComponentRename += new ComponentRenameEventHandler(OnComponentRename); } } /* This method handles the OnComponentChanged event to display a notification. */ private void OnComponentChanged(object sender, ComponentChangedEventArgs ce) { } /* This method handles the OnComponentChanging event to display a notification. */ private void OnComponentChanging(object sender, ComponentChangingEventArgs ce) { } /* This method handles the OnComponentAdded event to display a notification. */ private void OnComponentAdded(object sender, ComponentEventArgs ce) { if (this.DesignMode && ce.Component is EncapsColumnHeader) { //if (columnHeaders != null) // (ce.Component as EncapsColumnHeader).DisplayIndex = columnHeaders.Count; try { columnHeaders.Add(ce.Component as EncapsColumnHeader); } catch { } } } /* This method handles the OnComponentAdding event to display a notification. */ private void OnComponentAdding(object sender, ComponentEventArgs ce) { } /* This method handles the OnComponentRemoved event to display a notification. */ private void OnComponentRemoved(object sender, ComponentEventArgs ce) { OnUserChange("A component, " + ce.Component.Site.Name + ", has been removed."); } /* This method handles the OnComponentRemoving event to display a notification. */ private void OnComponentRemoving(object sender, ComponentEventArgs ce) { OnUserChange("Removing a component, " + ce.Component.Site.Name + "."); if (ce.Component is EncapsColumnHeader) { try { EncapsColumnHeader ch = (ce.Component as EncapsColumnHeader); int index = columnHeaders.IndexOf(ch); OnUserChange("index " + index.ToString()); OnUserChange("columnHeaders " + columnHeaders.Count.ToString()); OnUserChange("lvMain " + this.lvMain.Columns.Count.ToString()); columnHeaders.Remove(ch); } catch (Exception ex) { OnUserChange("Error " + ex.Message); } } } /* This method handles the OnComponentRename event to display a notification. */ private void OnComponentRename(object sender, ComponentRenameEventArgs ce) { } // This method adds a specified notification message to the control's listbox. private void OnUserChange(string text) { //listBox1.Items.Add(text); //listBox1.SelectedIndex = listBox1.Items.Count - 1; } public SelectionList() { columnHeaders.Owner = this; InitializeComponent(); } public class ColumnHeaderCollection : Collection<EncapsColumnHeader> { private SelectionList owner = null; public SelectionList Owner { set { owner = value; } } public new void Add(EncapsColumnHeader item) { this.Insert(this.Count, item); } public void AddRange(EncapsColumnHeader[] items) { foreach (EncapsColumnHeader hdr in items) this.Add(hdr); } public new void Clear() { this.owner.lvMain.Columns.Clear(); foreach (EncapsColumnHeader hdr in this) this.Remove(hdr); } public new void Insert(int index, EncapsColumnHeader item) { item.Owner = this.owner; //For first column header property TextAlign must be HorizontalAlignment.Left if (index == 0) item.TextAlign = HorizontalAlignment.Left; this.owner.lvMain.Columns.Insert(index, (ColumnHeader)item.ColumnHeader.Clone()); base.Insert(index, item); try { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this.owner.lvMain); PropertyDescriptor prop = properties.Find("Columns", true); prop.SetValue(this.owner, prop); } catch { } } public new void Remove(EncapsColumnHeader item) { int index = this.IndexOf(item); this.RemoveAt(index); } public new void RemoveAt(int index) { //If the column header being removed is the first, make sure the second is set to left alignment if (index == 0 && this.Count > 1) this[1].TextAlign = HorizontalAlignment.Left; this.owner.lvMain.Columns.RemoveAt(index); this[index].Owner = null; base.RemoveAt(index); try { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this.owner.lvMain); PropertyDescriptor prop = properties.Find("Columns", true); prop.SetValue(this.owner, prop); } catch { } } } private ColumnHeaderCollection columnHeaders = new ColumnHeaderCollection(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Editor(typeof(CollectionEditor), typeof(UITypeEditor))] public ColumnHeaderCollection Columns { get { return columnHeaders; } } private bool ShouldSerializeColumns() { return columnHeaders.Count() != 0; } [ToolboxItem(false), DesignTimeVisible(false), DefaultProperty("Text")] public class EncapsColumnHeader : Component, ICloneable { private SelectionList owner = null; public SelectionList Owner { set { owner = value; } } private int GetThisIndex() { int retval = -1; if (owner != null) retval = this.owner.columnHeaders.IndexOf(this); return retval; } private ColumnHeader columnMain; public ColumnHeader ColumnHeader { get { return columnMain; } } public EncapsColumnHeader() { columnMain = new ColumnHeader(); } public EncapsColumnHeader(int imageIndex) { columnMain = new ColumnHeader(imageIndex); } public EncapsColumnHeader(string imageKey) { columnMain = new ColumnHeader(imageKey); } [Localizable(true), RefreshProperties(RefreshProperties.Repaint), DefaultValue(-1)] public int DisplayIndex { get { return columnMain.DisplayIndex; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].DisplayIndex = value; } columnMain.DisplayIndex = value; } } [TypeConverter(typeof(ImageIndexConverter)), DefaultValue(-1), Editor("System.Windows.Forms.Design.ImageIndexEditor", typeof(UITypeEditor)), RefreshProperties(RefreshProperties.Repaint), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int ImageIndex { get { return columnMain.ImageIndex; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].ImageIndex = value; } columnMain.ImageIndex = value; } } [TypeConverter(typeof(ImageKeyConverter)), DefaultValue(""), Editor("System.Windows.Forms.Design.ImageIndexEditor", typeof(UITypeEditor)), RefreshProperties(RefreshProperties.Repaint), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string ImageKey { get { return columnMain.ImageKey; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].ImageKey = (string)value.Clone(); } columnMain.ImageKey = value; } } [Browsable(false)] public ImageList ImageList { get { return columnMain.ImageList; } } [Browsable(false)] public int Index { get { return columnMain.Index; } } [Browsable(false), DefaultValue("")] public string Name { get { return columnMain.Name; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].Name = (string)value.Clone(); } columnMain.Name = value; } } [Bindable(true), TypeConverter(typeof(StringConverter)), Localizable(false), DefaultValue(null)] public Object Tag { get { return columnMain.Tag; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].Tag = value; } columnMain.Tag = value; } } [Localizable(true), DefaultValue("ColumnHeader")] public string Text { get { return columnMain.Text; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].Text = (string)value.Clone(); } columnMain.Text = value; } } [Localizable(true), DefaultValue(HorizontalAlignment.Left)] public HorizontalAlignment TextAlign { get { return columnMain.TextAlign; } set { //the first column header MUST be set to HorizontalAlignment.Left int index = this.GetThisIndex(); if (index > -1) { if (index == 0) value = HorizontalAlignment.Left; this.owner.lvMain.Columns[index].TextAlign = value; } columnMain.TextAlign = value; } } [Localizable(true), DefaultValue(60)] public int Width { get { return columnMain.Width; } set { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].Width = value; } columnMain.Width = value; } } public void AutoResize(ColumnHeaderAutoResizeStyle headerAutoResize) { int index = this.GetThisIndex(); if (index > -1) { this.owner.lvMain.Columns[index].AutoResize(headerAutoResize); } columnMain.AutoResize(headerAutoResize); } public object Clone() { EncapsColumnHeader retval = new EncapsColumnHeader(); retval.columnMain = (ColumnHeader)this.columnMain.Clone(); return retval; } protected override void Dispose(bool disposing) { if (disposing == true) { columnMain.Dispose(); } base.Dispose(disposing); } public override string ToString() { return columnMain.ToString(); } } }
Viele Grüße,
Thorsten
- Typ geändert Aleksander Chalabashiev Freitag, 6. November 2015 08:36 keine bestätigte Lösung