public class Foo{
public string X {get; set;}
public string Y {get; set;}
}
If I want to use a ListView presented using a GridView inside it to present the values of both X and Y as columns you would write the following assuming the FooCollectionView is a collection view source or some other collection of Foo's
<ListView ItemsSource={Binding FooCollectionView}">
<ListView.View>
<GridView >
<GridViewColumn Header="X" DisplayMemberBinding="{Binding Path=X}" />
<GridViewColumn Header="Y" DisplayMemberBinding="{Binding Path=Age}" />
</GridView>
</ListView.View>
</ListView>
If you want to define a style or control template that applies to this control instead of the normal location, where you'd put a ContentPresenter in the template you put a GridViewRowPresenter. What happens if you use a ContentPresenter instead? You get the content presented but its not in a grid and its just the ToString() of the object. This obviously is not what you want to occur.
Therefore, it seems fairly obvious that you should use a GridViewRowPresenter. It however, is not that straightforward because what if you want to not use a GridView and instead just want to list them (the same as would be in a ListBox) so you have something like the following?
<ListView ItemsSource={Binding FooCollectionView}">
What happens when you define the style with GridViewRowPresenter to present the content? The ListView will appear to have no content because there is no GridView to present the content of. This does not present a huge problem if you are defining a style on a per ListView instance. However, it is a problem if you want to define a general style like you would in a theme. This presents a big problem because either you cannot use a GridView or must always use a GridView. You can get around this by using a ListBox anywhere you don't want to use a GridView. This strategy would mean letting the style dictate the form of the application which shouldn't be the case.
However, the real problem occurs when defining a reusable theme. If you want to define a general purpose theme that others can reuse without having to alter thier application such as in the WPFThems project then you need it be able to handle both cases. On a side-note some of the themes in WPFThemes use the ContentPresenter and some use the GridRowViewPresenter. This can make it so that the ListBox is shown properly with some themes applied and improperly with others.
The fix to this is a bit of a hack but ultimatley turns out to work. It basically involves defining both presenters inside the control template. So where you put the presenters you put code that looks like the following:
<GridViewRowPresenter x:Name="gridrowPresenter"
Content="{TemplateBinding Property=ContentControl.Content}"/>
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Property=ContentControl.Content}" Visibility="Collapsed"/>
To get the content to correctly display doing this. For the template the following trigger will need to be added:
<Trigger Property="GridView.ColumnCollection" Value="{x:Null}">
<Setter TargetName="contentPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
This trigger will show the ContentPresenter when the GridViewRowPresenter has no content. Since there is no GridView the GridViewRowPresenter will not display anything visually.
Obviously, this is a bit of a hack to get around a flaw with how WPF works. Hopefully, in a future version this will be addressed in how the framework works.
Edit 11/16/10 Added Visibility="Collapsed" property to the contentPresenter element which was a bug in the implementation
Hi,
ReplyDeleteI have the same problem. It seems impossible implementing a generic ListViewItem that works both for ListView and for ListView containing GridView. The hack you proposed does not seem to work in all scenarios... Sometimes happens that both ContentPresenter and GridViewRowPresenter are concurrently displayed...
Do you have a specific case where it is not working for you? Its been a while since I've looked at this problem. I don't think I had to make any changes to it for it to work in all the cases I was seeing. If you give me the case it doesn't work in I'm sure I can figure out how modify it so it works.
ReplyDeleteHi!
ReplyDeletehere you are an example in which your proposed solution doesn't work as expected: https://sites.google.com/site/mynetsamples/Home/ListViewStyle_Wrong.zip?attredirects=0&d=1
And here a final working solution that is based on your idea but also adds a Trigger in order to show/hide the ContentPresenter:
http://dotnetlearning.wordpress.com/2010/11/09/highlight-selected-item-listview-gridview-listviewitem/
You are correct. When I posted the solution I didn't add one key line. You need to have Visibility="Collapsed" on the contentPresenter element otherwise you will see shadowing in the case where the grid row presenter actually has a value. I've edited the post to reflect this.
ReplyDeleteWhen I came across this post I was a little dissapointed to find this seemed to be the only way. After much digging around I did find a nice little nugget that you may be interested in.
ReplyDeleteCheck out this slice of XAML, this is your golden ticket.
< Style x:Key="{x:Static GridView.GridViewItemContainerStyleKey}"
TargetType="{x:Type ListViewItem}" />
Cheers
ugg boots
ReplyDeletecheap jordans
rolex watches
coach outlet store
the north face outlet
canada goose jackets
gucci outlet
lebron james shoes 2016
nike free flyknit
polo ralph lauren outlet
20170217caiyan
ugg boots
ReplyDeletecheap jordans
rolex watches
coach outlet store
the north face outlet
canada goose jackets
gucci outlet
lebron james shoes 2016
nike free flyknit
polo ralph lauren outlet
20170217caiyan
michael kors
ReplyDeletejuicy couture outlet
baseball bats
converse
air jordan
insanity
balenciaga
soccer jerseys
christian louboutin
ferragamo
2017.11.20xukaimin
oakley outlet
ReplyDeletemichael kors handbags
chanel
nike free 5
abercrombie outlet
ferragamo handbags
prada
louboutin pas cher
ralph lauren
adidas flip-flops
2018.8.7zhouyanhua
mlb jerseys
ReplyDeletecoach outlet
oakley sunglasses
north face jackets
yeezy 500
under armour shoes
jordan shoes
coach handbags
miu miu shoes
giuseppe zanotti
chenlina20181013
longchamp
ReplyDeletechrome hearts
ferragamo belt
nike air max 97
michael jordan shoes
nike kd 11
jordan shoes
christian louboutin shoes
yeezy shoes
off white x jordan 1