Answered by:
Styling ContentMargin of ListViewItemPresenter in ListView

Question
-
Using a <ListView> with two-way binding to present a list of <TextBox>es. The binding is all working fine. Now I'm trying to visually tighten up the list as displayed so there isn't so much blank space between the <TextBox>es. I've dumped the visual tree. After data binding, <ListView> is generating the following pattern:
/* ListView Border ScrollViewer Border Grid ScrollContentPresenter ItemsPresenter ContentControl WrapGrid ListViewItem ListViewItemPresenter TextBox Grid Border Border ContentPresenter ScrollViewer Border Grid ScrollContentPresenter FrameworkElement ScrollBar ScrollBar Border ContentControl Button FrameworkElement */
Everything from <ListViewItem> down gets repeated for each collection item from the data binding.
Several of these elements have margins and other properties that are causing the undesired spacing. For example, normally <ListViewItem> has a non-zero Margin. I have used ListView.ItemContainerStyle to successfully target a style at the <ListViewItem> to set the Margin to all-zero.
The problem is trying to target styling at the various auto-generated wrapper elements. For example, <ListViewItemPresenter> has a ContentMargin=4,4,4,4. I cannot figure out how to target that property and set it to all-zero.
Visually I can see there are probably other margins/pads that are creating undesired space. However once I know the "trick" to setting the ContentMargin property of <ListViewItemPresenter> then I'll know the pattern to use to setting any other properties on other elements that I find.
Thanks!
-- kburgoyne
- Moved by Rob Caplan [MSFT]Microsoft employee, Moderator Sunday, February 2, 2014 5:53 AM
Friday, January 31, 2014 4:26 PM
Answers
-
You can use the designer's Edit Additional Templates menu to autogenerate a copy of the current template for editing. You can also find the default template in the documentation at ListViewItem styles and templates
- Marked as answer by kburgoyne Wednesday, February 5, 2014 11:40 PM
Wednesday, February 5, 2014 3:13 AMModerator
All replies
-
What language are you using so we can get you to a more appropriate forum?
You may be able to update that in PrepareContainerForItemOverride. You could also create a custom template with your desired ContentMargin setting.
--Rob
Saturday, February 1, 2014 8:12 AMModerator -
Hi Rob. C#. However I assumed the answer would be something in XAML.
-- kburgoyne
Saturday, February 1, 2014 8:37 AM -
Xaml is definitely a possibility. See my previous comment on overriding the template.
Either way this doesn't belong in the UI Design for Windows Store apps forum. I'll move it to a more appropriate one for you.
--Rob
Sunday, February 2, 2014 5:53 AMModerator -
Just hooked and did a visual tree dump of what was passed to PrepareContainerForItemOverride. It would appear that only <ListViewItem> is passed and none of the template from the XAML file has been included under it yet. So <ListViewItemPresenter> is not under the passed <ListViewItem> to be manipulated yet. If I have to manually expand the template, then I assume I can research and figure out how to do it but it is getting to be somewhat distant from trying to keep the view formatting in the XAML file.
Addition: I did call base.PrepareContainerForItemOverride before dumping the visual tree.
-- kburgoyne
- Edited by kburgoyne Monday, February 3, 2014 1:30 AM Addition
Monday, February 3, 2014 1:29 AM -
You can use the designer's Edit Additional Templates menu to autogenerate a copy of the current template for editing. You can also find the default template in the documentation at ListViewItem styles and templates
- Marked as answer by kburgoyne Wednesday, February 5, 2014 11:40 PM
Wednesday, February 5, 2014 3:13 AMModerator -
Thanks. I can see from the "ListViewItem styles and templates" page that it shows what I can use to solve the problem.
For anyone else looking to reduce the whitespace between items in a ListView, also pay attention to whether controls have scroll bars that are just disabled but not hidden. Or perhaps automatic but not currently showing. Disabled appears to leave the space for the scroll bars to appear when enabled. Hidden appears to successfully eliminate that whitespace allocation. So undesired spacing between controls may (or may not) be simply space that is being reserved so that a scroll bar can appear when needed without causing the layout to shift around.
When it comes to ListViewItemPresenter, I've been able to get my hands on it at various events during the ListView layout sequence, but at no point was I able to successfully eliminate the ContentMargin being set to 4,4,4,4. (Except presumably to go running back through the entire visual tree after the entire page has completed layout.) The reason becomes apparent when looking at the default ListView XAML shown at the previously referenced URL (ListViewItem styles and templates). The ListViewItemPresent sets the ContentMargin property to "4" as a hard assignment on the XAML element. That hard assignment directly on the element is pretty hard to override.
-- kburgoyne
Wednesday, February 5, 2014 11:47 PM