WPF ListView:单列中显示的图标视图
我遇到了一个奇怪的问题...
我想我想做的是相当标准的:允许用户在网格之间切换 和我的 ListView 中的图标模式。 一切都很顺利,但是...图标视图不是以换行方式显示项目,而是在单列中显示它们,每个项目占据视图的整个宽度。我无法指出到底出了什么问题...:-(
(我还没有在这个论坛上获得足够的 XP,并且它不允许我发布图像;我会给而是屏幕截图的链接)
我想要的: https://i.sstatic.net/ jYhVx.png
我有什么: https://i.sstatic.net/PeAae.png
这是 IconView 样式定义(在主题中\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>
它在相应的 Control 类中使用:
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");
}
}
}
以下是在 View.xaml 中使用所有这些的方式(我将省略将 {DynamicResource IconView} 分配给的 DataTrigger ListView 的视图,为了简洁起见):
<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"/>
我要疯了...而且,更让我沮丧的是,Snoop 没有看到我的应用程序:-(
请帮忙!;-)
非常感谢, 亚历克斯
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: https://i.sstatic.net/jYhVx.png
What I have: https://i.sstatic.net/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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
大多数绑定可能只是被破坏:
(ListView.View).ItemWidth
例如,上述路径的解释与您在
StoryBoard.TargetProperty
中使用的路径不同。如果在绑定中使用括号,则表示绑定到附加属性。来自 MSDN,强调我的:
因此,在上面的示例中分别更改它们:
View.ItemWidth
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:
So change those respectively, in the above example:
View.ItemWidth
嗯,我找到了罪魁祸首。
事实证明,问题不在于我在问题中包含的片段,而在于我遗漏的内容 - ListView 本身的 ListView.GroupStyle 定义。
删除它后,列表将按照我期望的方式显示。
感谢所有考虑我问题的人!
亚历克斯
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