对不起,我不知道如何更好地解释这个,但我想在数据网格中包装列。
我不是试图将文本包装在datagrid列中,而是包含datagrid的实际列。
我搜索了网络,我已经通过Adam Nathan浏览了WPF 4.5,很可能是因为我没有能力正确描述我想要做的事情,搜索只提出了文本包装。老实说,我不知道如何处理这个问题。
这是我对datagrid的XAML
<DataGrid Name="InfoCountTextBlock" ColumnWidth="100" Grid.Row="3" Grid.ColumnSpan="4" Margin="5" GridLinesVisibility="None" AlternationCount="2">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="White"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#ddebf7"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#338fff"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
这就是背后的代码,
foreach (string infoOption in InfoOptions)
{
infoCount.Add(
new InfoOption {
Info = infoOption,
Instances = filteredSelection.Count(staff => staff.Info_Data == infoOption)
}
);
}
InfoCountTextBlock.ItemsSource = infoCount;
这是为了说明我想要实现的目标。 就像现在一样。
这就是我想要实现的,我希望将数据保存在一个数据网格中,因为我可能最终将这些数据连接到DataBase。所以任意地,当数据超过5行时,它会移动到下一个列块,依此类推。
答案 0 :(得分:1)
右。现在我有一些时间,我实现了它。以下是步骤:
首先,我将定义样本数据类型和一些示例数据,以帮助在设计器内部直观地显示事物,而不必每次都运行它。由于您已经定义了数据类型,因此不需要执行此步骤。只是照顾一件事。我们的控件需要访问名为RowNumber
的属性来决定每个元素的行/列。这应该只是一个int
类型属性,显示集合中元素的行索引。
public class FiveRowData
{
public int RowNumber { get; set; }
public string Column1 { get; set; }
public string Column2 { get; set; }
}
public class FiveRowList : List<FiveRowData>
{
}
接下来,将一个示例xml数据文件(Add New Item&gt; Resource Dictionary)添加到项目中。这也不是必需的,仅用于设计时支持。将以下示例数据粘贴到文件中:
<YourProject:FiveRowList xmlns:YourProject="clr-namespace:YourProject" Capacity="37">
<YourProject:FiveRowData RowNumber="1" Column1="Content 1" Column2="Item 1" />
<YourProject:FiveRowData RowNumber="2" Column1="Content 2" Column2="Item 2" />
<YourProject:FiveRowData RowNumber="3" Column1="Content 3" Column2="Item 3" />
<YourProject:FiveRowData RowNumber="4" Column1="Content 4" Column2="Item 4" />
<YourProject:FiveRowData RowNumber="5" Column1="Content 5" Column2="Item 5" />
<YourProject:FiveRowData RowNumber="6" Column1="Content 6" Column2="Item 6" />
<YourProject:FiveRowData RowNumber="7" Column1="Content 7" Column2="Item 7" />
<YourProject:FiveRowData RowNumber="8" Column1="Content 8" Column2="Item 8" />
<YourProject:FiveRowData RowNumber="9" Column1="Content 9" Column2="Item 9" />
<YourProject:FiveRowData RowNumber="10" Column1="Content 10" Column2="Item 10" />
<YourProject:FiveRowData RowNumber="11" Column1="Content 11" Column2="Item 11" />
<YourProject:FiveRowData RowNumber="12" Column1="Content 12" Column2="Item 12" />
<YourProject:FiveRowData RowNumber="13" Column1="Content 13" Column2="Item 13" />
<YourProject:FiveRowData RowNumber="14" Column1="Content 14" Column2="Item 14" />
<YourProject:FiveRowData RowNumber="15" Column1="Content 15" Column2="Item 15" />
<YourProject:FiveRowData RowNumber="16" Column1="Content 16" Column2="Item 16" />
<YourProject:FiveRowData RowNumber="17" Column1="Content 17" Column2="Item 17" />
</YourProject:FiveRowList>
现在实际工作。在WPF项目中添加新的UserControl
。将其命名为FiveRowWrapper
(或任何您想要的,但请注意在以下代码中重命名)。转到XAML并使用以下代码替换现有代码:
<ItemsControl x:Class="FiveRowWrapper"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:YourProject"
xmlns:syswin="clr-namespace:System.Windows;assembly=PresentationFramework"
mc:Ignorable="d"
d:DesignHeight="180" d:DesignWidth="600"
d:DataContext="{d:DesignData Source=FiveRowListSampleData.xaml}"
ItemsSource="{Binding}">
<ItemsControl.Resources>
<local:ItemsCountToColCountConverter x:Key="ItemsCountToColCountConverter" />
<local:FiveRowToRowNumberConverter x:Key="FiveRowToRowNumberConverter" />
<local:FiveRowToColNumberConverter x:Key="FiveRowToColNumberConverter" />
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:FiveRowData">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Column1}" Margin="10" />
<TextBlock Text="{Binding Column2}" Margin="10" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid local:GridHelpers.RowCount="5"
local:GridHelpers.ColumnCount="{Binding Count, Converter={StaticResource ItemsCountToColCountConverter}}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Grid.Row" Value="{Binding RowNumber, Converter={StaticResource FiveRowToRowNumberConverter}}" />
<Setter Property="Grid.Column" Value="{Binding RowNumber, Converter={StaticResource FiveRowToColNumberConverter}}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
有几点要详述。我们使用ItemsControl
作为其面板使用Grid
。这将作为我们各个项目的整体容器。这些项目将依次使用上面定义的ItemTemplate
包含StackPanel
和TextBlock
个Column1
来显示每个项目的属性。对于我的示例课程,我使用了Column2
和ItemTemplate
属性,但您可以使用您的属性,甚至可以通过在此处定义自己的ItemContainerStyle
以您想要的任何方式自定义单个项目的外观。底部的Grid.Row
属性负责绑定每个项目的Grid.Column
和Grid
属性,从而将项目放入主Grid
内的适当单元格中。
上面的XAML代码还有另外两件事需要解释。首先,我们需要确定Grid
中的列数,这可以简单地通过将项目数除以5来计算。但问题是由于GridHelpers
的设计,我们不能将列数绑定到属性,并需要通过附加属性间接处理。
在项目中添加一个新类,并将其命名为public class GridHelpers
{
public static readonly DependencyProperty ColumnCountProperty = DependencyProperty.RegisterAttached("ColumnCount", typeof(int), typeof(GridHelpers), new PropertyMetadata(-1, ColumnCountChanged));
public static int GetColumnCount(DependencyObject obj)
{
return obj.GetValue(ColumnCountProperty);
}
public static void SetColumnCount(DependencyObject obj, int value)
{
obj.SetValue(ColumnCountProperty, value);
}
public static void ColumnCountChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || (int)e.NewValue < 0)
return;
Grid grid = (Grid)obj;
grid.ColumnDefinitions.Clear();
for (int i = 0; i <= (int)e.NewValue - 1; i++) {
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
}
}
}
(感谢Rachel's helpful answer)。用以下内容替换此文件的内容:
Grid
如您所见,此类将附加属性添加到GridLength.Auto
,使用该属性可以动态定义列数。我在这里使用public class ItemsCountToColCountConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)Math.Ceiling((int)value / 5f);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class FiveRowToRowNumberConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((int)value - 1) % 5f;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class FiveRowToColNumberConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)Math.Floor(((int)value - 1) / 5f);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
,但是如果你想要大小相等的列,你也可以使用固定大小的列。
最后,我们需要以下3个转换器: