问题
I'm experiencing a weird problem...
What I'm trying to do is quite standard, I guess: aloowing the user to switch between Grid and Icon modes in my ListView. All is going well, but... The Icon view, instead of showing the items in wrapping rows, shows them in a single column, with each item occupying the whole width of the view. And I can't put my finger on what exactly is wrong... :-(
(I haven't earned enough XP on this forum yet, and it won't allow me to post images; I'll give the links to the screenshots instead)
What I want: http://i.stack.imgur.com/jYhVx.png
What I have: http://i.stack.imgur.com/PeAae.png
Here's the IconView style definition (in Themes\Generic.xaml):
<Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type l:IconView}, ResourceId=IconViewStyle}"
TargetType="{x:Type ListView}"
BasedOn="{StaticResource {x:Type ListBox}}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="ItemContainerStyle" Value="{Binding (ListView.View).ItemContainerStyle, RelativeSource={RelativeSource Self}}"/>
<Setter Property="ItemTemplate" Value="{Binding (ListView.View).ItemTemplate, RelativeSource={RelativeSource Self}}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"
Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
It's used in the corresponding Control class:
public class IconView : ViewBase
{
public static readonly DependencyProperty ItemContainerStyleProperty =
ItemsControl.ItemContainerStyleProperty.AddOwner(typeof(IconView));
public Style ItemContainerStyle
{
get { return (Style)GetValue(ItemContainerStyleProperty); }
set { SetValue(ItemContainerStyleProperty, value); }
}
public static readonly DependencyProperty ItemTemplateProperty =
ItemsControl.ItemTemplateProperty.AddOwner(typeof(IconView));
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public static readonly DependencyProperty ItemWidthProperty =
WrapPanel.ItemWidthProperty.AddOwner(typeof(IconView));
public double ItemWidth
{
get { return (double)GetValue(ItemWidthProperty); }
set { SetValue(ItemWidthProperty, value); }
}
public static readonly DependencyProperty ItemHeightProperty =
WrapPanel.ItemHeightProperty.AddOwner(typeof(IconView));
public double ItemHeight
{
get { return (double)GetValue(ItemHeightProperty); }
set { SetValue(ItemHeightProperty, value); }
}
protected override object DefaultStyleKey
{
get
{
return new ComponentResourceKey(GetType(), "IconViewStyle");
}
}
}
And here's how all this is being used in the View.xaml (I'll omit the DataTrigger that assigns {DynamicResource IconView} to ListView's View, for brevity) :
<DataTemplate x:Key="IconViewItemTemplate">
<StackPanel Height="170" Width="170">
<Grid Width="150" Height="150" HorizontalAlignment="Center">
<Image Source="{Binding DefaultPicture.Path}" Margin="6,6,6,9"/>
</Grid>
<TextBlock Text="{Binding ID}" FontSize="13" HorizontalAlignment="Center" Margin="0,0,0,1" />
</StackPanel>
</DataTemplate>
<localControls:IconView x:Key="IconView"
ItemTemplate="{StaticResource IconViewItemTemplate}"
ItemWidth="180"/>
I am going nuts... And, to add to my frustration, Snoop doesn't see my application :-(
Please help! ;-)
Many thanks, Alex
回答1:
Most of your bindings might just be broken: (ListView.View).ItemWidth
The above path is interpreted differently than the paths you use in StoryBoard.TargetProperty for example. If you use parenthesis in a binding it signals a binding to an attached property.
From MSDN, emphasis mine:
The path is specified in XAML that is in a style or template that does not have a specified Target Type. A qualified usage is generally not valid for cases other than this, because in non-style, non-template cases, the property exists on an instance, not a type.
So change those respectively, in the above example: View.ItemWidth
回答2:
Well, I found the culprit. Turns out that problem is not in the snippets I included in the question, but rather in something I left out - the ListView.GroupStyle definition on the ListView itself. After removing it, the list is shown the way I expect it to be.
Thank you to everyone that considered my question!
Alex
来源:https://stackoverflow.com/questions/7404303/wpf-listview-icons-view-shown-in-a-single-column