Wpf 绑定列表<;列表<;MyClass>&燃气轮机;在网格中创建单元格
以下是我的一篇相关文章中的一些内容: 所以我有一个:Wpf 绑定列表<;列表<;MyClass>&燃气轮机;在网格中创建单元格,wpf,xaml,Wpf,Xaml,以下是我的一篇相关文章中的一些内容: 所以我有一个: List<List<FarmyardSpace>> 列表 我希望它被表示为网格单元格中的按钮。我不能像在相关文章中那样使用UniformGrid,因为我需要定义网格中单元格的大小。理想情况下,我不想在数据中定义行字段和列字段(尽管也许这应该由ViewModel来处理?前几天我刚开始学习这方面的知识,但我仍在关注WPF和MVVM) 下面是我最近的一次尝试,但没有成功(事实上引发了一个异常),在这个特定的示例中,我依
List<List<FarmyardSpace>>
列表
我希望它被表示为网格单元格中的按钮。我不能像在相关文章中那样使用UniformGrid,因为我需要定义网格中单元格的大小。理想情况下,我不想在数据中定义行字段和列字段(尽管也许这应该由ViewModel来处理?前几天我刚开始学习这方面的知识,但我仍在关注WPF和MVVM)
下面是我最近的一次尝试,但没有成功(事实上引发了一个异常),在这个特定的示例中,我依赖FarmyardSpace上现有的列和行属性:
<ItemsControl ItemsSource="{Binding FarmyardGrid}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding}">
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition />
<RowDefinition Height="15"/>
<RowDefinition />
<RowDefinition Height="15"/>
<RowDefinition />
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Row}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
我认为这不起作用的部分原因是外部ItemsControl包含的项不是FarmyardSpaces,而是List,因此它们没有要绑定的Column属性。我还尝试了使用内部ItemsControl中的RowDefinitions和ColumnDefinitions。这消除了异常,但也不起作用,对我来说似乎是错误的,特别是考虑到在相关文章中使用UniformGrid时的解决方案,其中列在外部ItemsControl中声明
无论如何,我会感谢任何人帮我解决这个问题,提前谢谢 如果集合项上的属性指定了它们在网格中的位置,那么这显然是最简单的,这就是您现在设置的。如果没有,您可以使用转换器为您计算每个项目的索引,然后将其指定为行/列值,并且在两个维度中的工作方式相同。以下是基本的转换器:
public class ItemToIndexConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
object item = values.FirstOrDefault();
IList collection = values.OfType<IList>().LastOrDefault();
if (collection == null || item == null)
return 0;
return collection.IndexOf(item);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<ItemsControl ItemsSource="{Binding FarmyardGrid}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition />
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:ItemToIndexConverter/>
</MultiBinding.Converter>
<Binding/>
<Binding Path="ItemsSource"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Column">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:ItemToIndexConverter/>
</MultiBinding.Converter>
<Binding/>
<Binding Path="ItemsSource"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
公共类ItemToIndexConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
对象项=值。FirstOrDefault();
IList collection=values.OfType().LastOrDefault();
if(集合==null | |项==null)
返回0;
返回集合。索引(项目);
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
和修改后的XAML版本(减少到3x3),将当前项和父项控件中的完整集合传递到转换器:
public class ItemToIndexConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
object item = values.FirstOrDefault();
IList collection = values.OfType<IList>().LastOrDefault();
if (collection == null || item == null)
return 0;
return collection.IndexOf(item);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<ItemsControl ItemsSource="{Binding FarmyardGrid}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition />
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:ItemToIndexConverter/>
</MultiBinding.Converter>
<Binding/>
<Binding Path="ItemsSource"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition />
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Column">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<local:ItemToIndexConverter/>
</MultiBinding.Converter>
<Binding/>
<Binding Path="ItemsSource"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
好吧,现在我自己没有得到这个,我并不觉得很糟糕:)这个解决方案对我来说很有意义,但我认为会有一种不太复杂的方法来处理索引,因为这似乎是一件非常基本的事情,我想知道它的布局目的。谢谢你的帮助!