使用带有ExpandoObjects集合的ItemSource在DataGrid中进行TextWrapping

时间:2016-04-20 08:27:47

标签: wpf xaml gridview

我把我的单元格包装起来有些麻烦,它们只是走出界限,当我看到可视树时我可以看到在contentpresenter里面它看到了一个文本块,我尝试在内容上设置一个样式演示者,但是当我看到属性时,它说没有包装。

我不知道如何使用数据模板,使其成为绑定到gridview的expando对象列表,其中动态属性由列名绑定。所以我不知道如何绑定text =“{dynamic dynamicproperty}。因此我试图在内容演示者上更改它。

    <Grid HorizontalAlignment="Center" Grid.Row="1">
        <DataGrid HeadersVisibility="None"
                  ItemsSource="{Binding SheetData}"
                  Background="Transparent"
                  AutoGenerateColumns="False"
                  ColumnWidth="*"
                  IsHitTestVisible="False"
                  BorderThickness="0,2,0,0"
                  UseLayoutRounding="True"
                  BorderBrush="White"
                  RowBackground="Transparent"
                  MaxWidth="700"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                  HorizontalGridLinesBrush="White"
                  VerticalGridLinesBrush="White"
                  Behaviors:GridViewBindingBehavior.ColumnsCollection="{Binding ColumnData}"           
                  VerticalAlignment="Top"
                  HorizontalContentAlignment="Left"
                  Width="auto">
            <DataGrid.RowHeaderTemplate>
                <DataTemplate>
                    <TextBlock Margin="5,0" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                   AncestorType={x:Type DataGridRow}}, 
                                  Path=Item.RowIndex}"/>
                </DataTemplate>
            </DataGrid.RowHeaderTemplate>

            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell">
                    <Setter Property="Padding" Value="8, 7"/>
                    <Setter Property="BorderThickness" Value="2" />

                    <Setter Property="BorderBrush" Value="White" />
                    <Setter Property="Background" Value="#f1f2f4" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type DataGridCell}">
                                <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                                    <ContentPresenter>
                                        <ContentPresenter.Resources>
                                            <Style TargetType="{x:Type TextBlock}" >
                                                <Setter Property="TextWrapping" Value="WrapWithOverflow"/>
                                                <Setter Property="Height" Value="auto"/>
                                                <Setter Property="Width" Value="auto"/>
                                            </Style>
                                        </ContentPresenter.Resources>
                                    </ContentPresenter>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.CellStyle>

        </DataGrid>
    </Grid>

编辑: 因为我不认为我能够在其中使用带有TextBlock的DataTemplate,由于我绑定列的方式,从我的附加行为,也许有一种方法可以从代码中添加Text包装。我使用了来自here的附加行为。

这是我的附加行为:

public class GridViewBindingBehavior
{
    public static readonly DependencyProperty ColumnsCollectionProperty = DependencyProperty.RegisterAttached("ColumnsCollection", typeof(ObservableCollection<DataGridColumns>), typeof(GridViewBindingBehavior), new PropertyMetadata(OnColumnsCollectionChanged));

    public static void SetColumnsCollection(DependencyObject o, ObservableCollection<ColumnDefinition> value)
    {
        o.SetValue(ColumnsCollectionProperty, value);
    }

    public static ObservableCollection<ColumnDefinition> GetColumnsCollection(DependencyObject o)
    {
        return o.GetValue(ColumnsCollectionProperty) as ObservableCollection<ColumnDefinition>;
    }

    private static void OnColumnsCollectionChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        DataGrid gridView = o as DataGrid;

        if (gridView == null)
        {
            return;
        }

        gridView.Columns.Clear();

        if (gridView.ItemsSource == null)
        {
            return;
        }

        ObservableCollection<ExpandoObject> objExpando = (ObservableCollection<ExpandoObject>)gridView.ItemsSource;

        if (e.NewValue == null)
        {
            return;
        }

        var collection = e.NewValue as ObservableCollection<DataGridColumns>;

        if (collection == null)
        {
            return;
        }
        foreach (var column in collection)
        {
            var gridViewColumn = GetDataColumn(column);
            gridView.Columns.Add(gridViewColumn);
        }

    }

    private static DataGridTextColumn GetDataColumn(DataGridColumns columnName)
    {
        var column = new DataGridTextColumn();
        column.IsReadOnly = true;
        column.Header = columnName.DisplayColumnName;

        Binding binding = new Binding();
        binding.Converter = new ColumnValueConverter();
        binding.ConverterParameter = columnName.BindingPropertyName;
        column.Binding = binding;

        return column;
    }
}

编辑2:

我设法让它与价值转换器一起使用。唯一的问题是他们找到我所在的实际行是如此丑陋,是否有办法将datagrid绑定到第二个绑定。我看到datagrid有CurrentColumn属性,但我认为这是用于选择,并且在转换器内部时为null。

更新了datagrid:

        <DataGrid HeadersVisibility="None"
                  ItemsSource="{Binding SheetData}"
                  Background="Transparent"
                  AutoGenerateColumns="False"
                  ColumnWidth="*"
                  BorderThickness="0,2,0,0"
                  UseLayoutRounding="True"
                  BorderBrush="White"
                  RowBackground="Transparent"
                  MaxWidth="700"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                  HorizontalGridLinesBrush="White"
                  VerticalGridLinesBrush="White"
                  Behaviors:GridViewBindingBehavior.ColumnsCollection="{Binding ColumnData}"           
                  VerticalAlignment="Top"
                  HorizontalContentAlignment="Left"
                  Width="auto">
            <DataGrid.RowHeaderTemplate>
                <DataTemplate>
                    <TextBlock Margin="5,0" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                   AncestorType={x:Type DataGridRow}}, 
                                  Path=Item.RowIndex}"/>
                </DataTemplate>
            </DataGrid.RowHeaderTemplate>

            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell">
                    <Setter Property="Padding" Value="8, 7"/>
                    <Setter Property="BorderThickness" Value="2" />
                    <Setter Property="BorderBrush" Value="White" />
                    <Setter Property="Background" Value="#f1f2f4" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type DataGridCell}">
                                <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                                    <TextBlock TextWrapping="WrapWithOverflow" >
                                        <TextBlock.Text>
                                            <MultiBinding  Converter="{StaticResource columnConver}">
                                                <Binding Path="." />
                                                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}" Path="." />
                                            </MultiBinding>
                                        </TextBlock.Text>
                                    </TextBlock>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.CellStyle>

        </DataGrid>

丑陋的价值转换器:

public class ColumnMultiValueConverter : IMultiValueConverter
{
    private static int columnIndex = 0;
    private static int lastCount = 0;
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {

        var row = values[0] as IDictionary<string, object>;
        if (row == null)
            return row;

        var datagrid = values[1] as DataGrid;
        if (columnIndex >= datagrid.Columns.Count || lastCount != datagrid.Columns.Count)
            columnIndex = 0;

        var result = (row[datagrid.Columns[columnIndex].Header.ToString()]);
        columnIndex++;
        lastCount = datagrid.Columns.Count;
        return (result as GridCell)?.Value?.ToString();
    }

这可能需要成为一个新的问题,因为包装完成了。 只是我的代码变得非常难看。

0 个答案:

没有答案