WPF ListView: Icons view shown in a single column

被刻印的时光 ゝ 提交于 2019-12-24 11:07:03

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!