2017-11-08 30 views
1

クラス内でインデックス付きプロパティを作成しましたが、DataGrid(インデックス付きプロパティの各項目に対応する各セル)にDataGridTemplateColumnの各セルのバインディングを設定する必要があります。インデックス付きプロパティへのDataGridセルのバインド

作業スケジュール生成アプリケーション用です。グリッド内の各セルは、従業員およびシフトに関連するデータを表示します。シフト内の従業員が増えると、グリッドが右に増加し、つまり列が追加されます。グリッドは、データベーステーブルにバインドされていないプログラムで作成され、埋められたデータ構造を表示します。このフォーラムでのプレゼンテーションとコード検査を簡単にするために、私はすべてを本質的なものに減らしました。ここで

は写真です:

enter image description here

私は適切にバインディングを設定することはできませんので、これは、明らかに間違っています。 StackPanelのフィールドをインデックス付きプロパティの最初のアイテム(または他のアイテム)にバインドできますが、インデックス付き/パラメータ化された設定はバインドできません。

<Grid HorizontalAlignment="Left"> 
    <DataGrid x:Name="grdSch" HorizontalAlignment="Left" Height="400" VerticalAlignment="Top" Margin="8,0,0,0" AutoGenerateColumns="False" SelectionUnit="Cell"/> 
</Grid> 
<Page.Resources> 
    <DataTemplate x:Key="SPI_Template"> 
     <StackPanel> 
      <TextBlock Text="{Binding Path=shftDate}"/> 
      <TextBlock Text="{Binding Path=shftKind}"/> 
     </StackPanel> 
    </DataTemplate> 
    <DataTemplate x:Key="SEI_Template"> 
     <StackPanel> 
      <TextBlock Text="{Binding Path=data[0].emplName}"/> 
      <TextBlock Text="{Binding Path=data[0].shftTime}"/> 
     </StackPanel> 
    </DataTemplate> 
</Page.Resources> 

と列を生成するコード:data[]プロパティがインデックス化され

private void Page_Loaded(object sender, RoutedEventArgs e) 
    { 
     // Create the grid columns 
     DataGridTemplateColumn col = new DataGridTemplateColumn(); 
     col.Header = "Shift"; 
     col.CellTemplate = (DataTemplate)FindResource("SPI_Template"); 
     grdSch.Columns.Add(col); 
     for (int i = 0; i < 30; i++) 
     { 
      col = new DataGridTemplateColumn(); 
      col.Header = "Employee " + (i + 1); 
      col.Width = 100; 
      col.CellTemplate = (DataTemplate)FindResource("SEI_Template"); 
      // for now show only the 5 first elements 
      col.Visibility = i >= 5 ? Visibility.Hidden : Visibility.Visible; 
      grdSch.Columns.Add(col); 
     } 
    } 

はここ(の一部)私のXAMLです。現在のバインディング(例:"{Binding Path=data[0].emplName}")は、プロパティの1番目の項目で機能します。私が"{Binding Path=data[1].emplName}"に変更すると、2番目のものにバインドされます。しかし、これは私がもちろん必要なものではありません。バインディングを変更する方法はありますか?"{Binding Path=data[Grid.ColumnIndex-1].emplName}"? "パラメータ化されたバインディング"などについていくつかの記事を検索して見つけましたが、かなり明白で簡単なものは見つかりませんでした。もちろん、私は愚かなやり方でxamlに30の同様のテンプレートを追加することができます(インデックス付きのプロパティのインデックスだけが異なります) - これは間違いなく機能しますが、より良い方法でそれを作成しようとしています。

誰かが助けてくれますか?

は、事前にありがとう

答えて

1

一つの解決策は、我々はセルの内容をバインドするために使用する追加のBindingプロパティを公開します(DataGridTemplateColumn由来)カスタム列タイプを作成することです。ここでは、列のコードがあります:

public class DataGridBoundColumn : DataGridTemplateColumn 
{ 
    public BindingBase Binding { get; set; } 

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     var element = base.GenerateEditingElement(cell, dataItem); 
     if (element != null && Binding != null) 
      element.SetBinding(ContentPresenter.ContentProperty, Binding); 
     return element; 
    } 

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     var element = base.GenerateElement(cell, dataItem); 
     if (element != null && Binding != null) 
      element.SetBinding(ContentPresenter.ContentProperty, Binding); 
     return element; 
    } 
} 

その後、我々はわずか列生成コードを変更する必要があります。

private void Page_Loaded(object sender, RoutedEventArgs e) 
{ 
    var col = new DataGridTemplateColumn 
    { 
     Header = "Shift", 
     CellTemplate = (DataTemplate)FindResource("SPI_Template") 
    }; 
    grdSch.Columns.Add(col); 
    for (int i = 0; i < 30; i++) 
    { 
     col = new DataGridBoundColumn 
     { 
      Header = "Employee " + (i + 1), 
      Binding = new Binding($"data[{i}]"), 
      Width = 100, 
      CellTemplate = (DataTemplate)FindResource("SEI_Template"), 
     }; 
     grdSch.Columns.Add(col); 
    } 
} 

最後に、私たち生成された列はすでにdata[i]が表示されているので、我々はそれに応じSEI_Templateを変更する必要があります。

<DataTemplate x:Key="SEI_Template"> 
    <StackPanel> 
     <TextBlock Text="{Binding emplName}" /> 
     <TextBlock Text="{Binding shftDate}" /> 
    </StackPanel> 
</DataTemplate> 
+0

多くの、多くのありがとう!あなたが提案したようにコードを変更し、それは動作します。したがって、xamlのバインディングをインデックス付きの要素に設定するのではなく、基本的にインデックス付きプロパティの各項目に直接セルをバインドします。これは私が後にしたものでしたが、あなたのソリューションはうまくいきましたので、大丈夫です。再度、感謝します! –

関連する問題