4

My environment is Visual Studio 2012 Express.
I have a usercontrol that contains a ListView.
I need to let the user set at least the ListView appearance, so I exposed the Columns property :

[ in usercontrol ]

public ListView.ColumnHeaderCollection  Columns {  
    get { return listView.Columns; }  
}  

When I put the control on a form, the Columns property shows up in the Properties panel and
I am able to add columns and so on.
Yet, at runtime the columns are not displayed ( although the View property is set to Details ).
Am I missing something ?

Update

I think this may be of some interest so I'll elaborate my comment at Hans Passant below :

I created a dummy UserControl with an embedded ListView, exposing its Columns and View properties as public.
This allows to edit them from the Properties panel.
When editing the embedded ListView in the IDE using the ColumnHeaders collection editor,
the resulting code in the Form Designer class looks like this :

...  
//  
// userControl1  
//  
this.userControl1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {  
this.columnHeader1,  
this.columnHeader2});  
this.userControl1.Location = new System.Drawing.Point(12, 12);  
this.userControl1.Name = "userControl1";  
this.userControl1.Size = new System.Drawing.Size(260, 161);  
this.userControl1.TabIndex = 0;  
...  

Since I set the View to Details, there should be one more line :

this.userControl1.View = System.Windows.Forms.View.Details;  

Without this line, the ListView won't display the column headers at runtime.
Somehow, the IDE fails to put the line in the Form Designer; if the line is added by hand, it works as expected.
The puzzling thing is that I added a debug message in the Form_Load event sink

private void Form1_Load(object sender, EventArgs e) {  
    MessageBox.Show("Columns : " + userControl1.Columns.Count + "\r\nView : " + 
    userControl1.View.ToString());      
}  

and it displays View : Details in both cases.

Jack Griffin
  • 1,228
  • 10
  • 17
  • Sounds like the columns collection is not being serialized. Does the LV columns editor come up in the IDE? – Ňɏssa Pøngjǣrdenlarp Dec 27 '14 at 14:42
  • Yes, it does. As I stated, I am able to edit the column headers. – Jack Griffin Dec 27 '14 at 14:45
  • 1
    Your property has no setter, but I am not sure that will help with a UserControl. I think you will have to manually collect and serialize the collection, then feed them to the UC at start up. – Ňɏssa Pøngjǣrdenlarp Dec 27 '14 at 14:50
  • The ListView.Columns is a read-only property, that's why there is no setter. I'll do what you're suggesting if I have to, even though it sounds odd to me there is no other (simple) way to fix the problem. – Jack Griffin Dec 27 '14 at 15:00
  • Ahh, and so it should be. The core issue is that the contents etc of a UC are supposed to be fixed/static. It has be be a compiled object to be used on the form. As such, you cant alter what has already happened in InitializeComponent. Since you do not have a simple control, the solution will not be simple. – Ňɏssa Pøngjǣrdenlarp Dec 27 '14 at 15:03
  • I just edited the columns, saved and closed the solution and then opened it again : the changes are *not* saved. Can you give me a hint about how to proceed ? – Jack Griffin Dec 27 '14 at 15:08
  • @Hans Passant : thanks, that did the trick - now the columns are saved between sessions. But what about the runtime problem ? – Jack Griffin Dec 27 '14 at 15:16
  • It works fine at runtime, you probably collected junk in the Designer.cs file will trying to make the previous version work. – Hans Passant Dec 27 '14 at 15:18
  • Well, I don't know what happened exactly, but I put some debug code in the Form_Load event sink and it worked as expected.Then I commented it out completely, and now I works! Go figure! Thanks to both of you for your time. – Jack Griffin Dec 27 '14 at 15:28
  • It's late for a Merry Xmas, but have a Happy New Year ! – Jack Griffin Dec 27 '14 at 15:42
  • @Hans Passant : I did a test on a new usercontrol with an embedded ListView and discovered that the View property was not properly set ( even using your suggestion ) in the Form Designer. Added it by hand and that resolved the problem. Post the answer, so I'll vote you. – Jack Griffin Dec 27 '14 at 21:56

2 Answers2

4

You need to apply an attribute to override the default code serialization:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
public ListView.ColumnHeaderCollection  Columns {  
    get { return listView.Columns; }  
} 

The more general solution is to put the entire ListView into design mode after the UserControl was dropped on the form. That lets you change all the properties of the ListView, you probably won't need your Columns property anymore. Check this post to see how to do that.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

I had the same issue for VB.NET

I added columns in the designer and had the ListView.View to details but on runtime my columns disappeared even though they were visible in the designer.

So I deleted all columns in the designer and created them with code.

Private Sub InitListView()
    Dim listView As New ListView
    listView.Columns.Add("Test", 100, HorizontalAlignment.Left)
    listView.Dock = DockStyle.Fill
    listView.View = View.Details

    Me.panelListView.Controls.Add(listView)
End Sub

But I also have a Panel with Dockstyle.Top and a FlowLayoutPanel with Dockstyle.Bottom which contain control objects to interact with the user.

Adding the ListView to my UserControl.Controls with DockStyle.Fill worked in the designer but made my column disappear again on runtime.

The solution was to create a Panel in the designer and set it to Dockstyle.Fill.

As you can see in my code snippet I can set my ListView to Dockstyle.Fill and add it to the panel. This works fine and my column is visible now.

Matthis Kohli
  • 1,877
  • 1
  • 21
  • 23