【发布时间】:2018-01-26 06:03:44
【问题描述】:
我想在 ListView 中对齐视图模型项目(来自源),并将 WrapPanel 作为 ItemsPanel,以便项目基本上在两列中对齐,但如果项目比一列宽,它换行,从而使其 row 更高。
我想通过 Grid 控件来实现这一点Grid.
所以,我创建了以下 XAML:
<Grid>
<Grid.ColumnDefinitions>
<!--The column to bind from is a bit less wide than 50% to enable some margin between items in the same row.-->
<ColumnDefinition x:Name="clm1" Width="45*"/>
<ColumnDefinition Width="55*"/>
</Grid.ColumnDefinitions>
<ListView Grid.ColumnSpan="2" Width="some width" Height="some height" ItemsSource="some source">
<!--the wrap panel that wraps items after two is in a row-->
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemWidth="{Binding ActualWidth, ElementName=clm1}" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<!--some properties are binded to the view model object in the DataContext-->
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}">
<!--separate TextBlock is for text wrapping-->
<TextBlock Text="{Binding Text}" TextWrapping="Wrap"/>
</CheckBox>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
但是,这不起作用,项目在常规 WrapPanel 中对齐,而不是在列中。
这不起作用的原因:我检查了(在 Live Property Explorer 中)binding 到 ActualWidth 的值是什么,它是 double.NaN , 尽管ActualWidth 属性具有正常的数值。
所以主要问题是:为什么 binding 不起作用? (而第二个问题是:如何正确实现所需的layout?)
【问题讨论】:
-
由于 WrapPanel 位于模板内,因此您尝试绑定的列可能超出范围——这意味着 WrapPanel 不知道元素“clm1”。一种替代方法是将 clm1 的实际宽度绑定到 Window/Page 的数据上下文中的属性,然后将 WrapPanel 的宽度绑定到相同的属性。如果 DataContext 实现 INotifyPropertyChanged 并且您在 Width 属性更新时触发属性更改通知,这应该可以工作
-
@J.D.那么我是否必须为此目的创建一个具有依赖属性的新类?
-
如何向 ListView 提供数据?是通过绑定到视图模型中的数据源吗?或者你正在使用代码隐藏?如果你有一个视图模型,你可以在那里添加属性(如果你的视图模型实现了 INotifyPropertyChanged)。
-
@J.D.哦,好的,现在我明白了。如果您将建议作为答案发布,我会接受。顺便说一句,您是否认为在视图模型类中创建这样的属性是一种优雅的解决方案?我的意思是,这实际上是视图模型对象的用途吗?
标签: c# wpf xaml layout data-binding