6

これは私を夢中にさせています。コードで DataGrid を作成し、それをデータテーブルにバインドしています。これは動的であり、グリッドが作成されるたびに行と列が異なります。

基本的に、データテーブルをループして、次のように各列の DataGrid 列を作成します。

private static void CreateDataGridColumns(DataGrid datagrid, Document doc)
{
    if (doc == null) return; //return 

    datagrid.Columns.Clear();
    foreach (var item in doc.Keys)
    {
        var column = new DataGridTemplateColumn
        {
           Header = item,
           CellTemplateSelector = new CustomRowDataTemplateSelector(),
         };

        datagrid.Columns.Add(column);
    }
}

ご覧のとおり、カスタム データ テンプレート セレクターを使用しているため、コンテンツに応じてセルを異なる方法でレンダリングできます。

テンプレートセレクターはこちら

public class CustomRowDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate
        SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        var presenter = container as ContentPresenter;
        var gridCell = presenter.Parent as DataGridCell;

        if (element != null && item != null && gridCell != null)
        {
            var row = item as DataRow;

            if (row != null)
            {
                var cellObject = row[gridCell.Column.DisplayIndex];

                //set template based on cell type

                if (cellObject is DateTime)
                {
                    return element.FindResource("dateCell") as DataTemplate;
                }

                return element.FindResource("stringCell") as DataTemplate;
            }


        }

        return null;
    }
}

これが私のstringCell DataTemplateです

<DataTemplate x:Key="stringCell">
    <StackPanel>
        <TextBlock Style="{StaticResource cellStyle}" 
                    Grid.Row="0" Grid.Column="0" 
                    Text="{Binding Converter={StaticResource cellConverter}}" />
    </StackPanel>
</DataTemplate>

問題は、テンプレートセレクターが各セルに対して呼び出されることです (予想どおり) が、それがどのセルであるかがわからないため、TextBlock にテキストを設定する方法がわかりません。私はこのようなことをしたいと思います

<DataTemplate x:Key="stringCell">
    <StackPanel>
        <TextBlock Style="{StaticResource cellStyle}" 
                    Grid.Row="0" Grid.Column="0" 
                    Text="{Binding Path=Row[CellIndex], Converter={StaticResource cellConverter}}" />
    </StackPanel>
</DataTemplate>

しかし、CellIndex を取得するために利用できるものはありません。Path=Row[CellIndex] を設定できる場所で、これと同様のことを行うにはどうすればよいですか

4

2 に答える 2

0

コードでバインディングを作成してみることができます。このようなものが動作するはずです

var bind = new Binding(gridCell.Column.Header.ToString())
bind.Mode = BindingMode.TwoWay;
bind.Source = row;
BindingOperations.SetBinding(YourTextBlock, TextBlock.TextProperty, bind);
于 2016-07-11T15:24:24.663 に答える
-1

機能的に何を達成しようとしているのかわかりません。コードでそれを行うとうまくいくかもしれません。プロパティ DisplayValue を持つ、より高いレベルのクラスである CellClass を作成します。日付と文字列の実装。Path=DisplayValue で Source を CellClass にバインドします。List CellClasses を作成し、CellClass[0]、CellClass[1] にバインドすることもできます...これは私と同じように機能しますが、探している機能を提供するかどうかはわかりません。

    public abstract class CellClass
    {
         public abstract String DispValue { get; }
    }
    public class CellClassDate : CellClass
    {
         public override String DispValue { get ...; }
         public DateTime DateValue { get .. set ... }
    }
    public class CellClassString : CellClass
    {
         public override String DispValue { get ...; }
         public DateTime StringValue { get .. set ... }
    }
于 2011-07-22T21:36:17.143 に答える