2011-10-12 67 views
0

我試圖在DataGridTemplateColumn中創建組合框,但它應該包含取決於行的不同值。這是我的代碼:DataGrid中的每一行都不會調用ComboBox的綁定

<dg:DataGridTemplateColumn x:Name ="NameColumn" Header="Player Name"> 
    <dg:DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <ComboBox 
       SelectedValue="0" 
       DisplayMemberPath="FullName" 
       SelectedValuePath="Id" 
       ItemsSource="{Binding AllPlayers, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"/> 
     </DataTemplate> 
    </dg:DataGridTemplateColumn.CellTemplate> 
</dg:DataGridTemplateColumn> 

AllPlayers將在每次調用後返回不同的列表。

public List<Player> AllPlayers 
{ 
    get 
    { 
     counter = counter + 1; 
     Debug.Print("getting all players " + counter); 

     List<Player> lst = new List<Player>(); 

     for (int i=0; i < 5; i++) 
     { 
      Player p = new Player(); 
      p.Id = counter + i; 
      p.FullName = "Name " + counter + i; 
      lst.Add(p); 
     } 

     return lst; 
    } 
} 

出於某種原因,AllPlayers函數被調用用於第一39行,然後將數據從先前創建的列表採取。我可以從調試信息中看到(它在39次調用後停止打印)。而且組合框中的列表也不是唯一的。我不明白這種行爲背後的邏輯。我需要爲每一行調用AllPlayers。

回答

0

顯示您對網格的綁定。我會讓玩家成爲你綁定到網格的集合的公共屬性。在列表中的39以上的Ctor在那裏建立AllPlayers。讓我們假設你的39+名單是球隊,並且有屬性名稱,經理,城市,球員。即使你獲得了模板中的玩家,他們也不會直接與團隊相關聯(沒有走視覺樹)。

+0

我無法更改綁定到datagrid的集合,因爲它是從DataLayer自動生成的DataTable。 – sergman

+0

我知道你不會喜歡這個答案,但你可以從DataTable構建一個自定義對象並綁定到該對象。爲了高效使用DataReader。如果您正在使用DataTable的高級功能(如編輯功能),那麼這種功能的吸引力就更小了。您可以使用Relation創建一個DataSet並手動將您的Player添加到DataSet中。我在Windows窗體中進行了綁定,但是自從WPF和List以及ObservableCollection之後,我已經離開了DataSets。 – Paparazzi

0

你的方法是不正確的..首先你不應該相信數據網格虛擬化發生的順序。因此,基於計數器的加載不同列表的方法發生了不正常的情況。

當數據網格行被去虛擬化時,您的組合框將變爲可見並需要項源,並從Window.AllPlayers屬性中獲取它。但counter的順序將基於滾動而被擰緊。如果您突然滾動跳過幾行範圍,或者如果您使用延遲滾動,那麼counter將始終是錯誤的。如果你來回滾動counter將被擰緊(因爲我沒有看到任何代碼遞減計數器)...

所以底線是請不要使用這種方法。

現在你說你不想從單個項目加載列表。變量counter可能是指數據網格ItemsSource中當前行的Index。如果是這樣,你至少可以使用一個多轉換器。

組合框XAML:

<ComboBox 
     SelectedValue="0" 
     DisplayMemberPath="FullName" 
     SelectedValuePath="Id" > 
     <ComboBox.ItemsSource> 
      <MultiBinding Converter="{StaticResource RowWiseListConverter}"> 
       <!--The current row item--> 
       <Binding BindsDirectlyToSource="True" /> 

       <!---The items source of the data grid.--> 
       <Binding Path="ItemsSource" 
         RelativeSource="{RelativeSource 
           AncestorType={x:Type DataGrid}}"/> 
      </MultiBinding> 
     </ComboBox.ItemsSource> 
    </ComboBox> 

多轉換器的代碼:

public class RowWiseListConverter : IMultiValueConverter 
{ 
    public object Convert(
      object[] values, 
      Type targetType, 
      object parameter, 
      CultureInfo culture) 
    { 
     var item = values[0]; 
     var list = values[1] as System.Collections.IEnumerable; 

     if (item != null && list != null) 
     { 
      var counter = list.Cast<object>().ToList().IndexOf(item); 

      List<Player> lst = new List<Player>(); 
      for (int i = 0; i < 5; i++) 
      { 
       Player p = new Player(); 
       p.Id = counter + i; 
       p.FullName = "Name " + counter + i; 
       lst.Add(p); 
      } 

      return lst; 
     } 

     return null; 
    } 
    ..... 
} 

該代碼是僅用於說明目的,並且可能無法編譯。

希望這會有所幫助。

0

我沒有使用計數器來計算索引,只是爲了調試目的來計算函數被調用的次數,並使用它來爲每個組合框創建唯一列表。我的原始代碼與您提供的方法相同。這裏是轉換器:

Public Function Convert(ByVal value() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert 
    Dim playerReportRow As MainAdminDS.PlayerReportRow = value(0).Row 
    'Dim sourceList As MainAdminDS.PRSourceDataTable = SmallReportForm.GetSmallReportForm().PRSource 
    Dim sourceList As MainAdminDS.PRSourceDataTable = value(1) 

    Dim sourceListView As New List(Of MainAdminDS.PRSourceRow) 

    Dim rand As New Random 
    For i As Integer = 0 To sourceList.Count - 1 
     If (sourceList(i).PRSource_Id = playerReportRow.PlayerReport_Source Or rand.Next(0, 2) = 0) Then 
      sourceListView.Add(sourceList(i)) 
     End If 
    Next 

    Return sourceListView 
End Function 

我再次創建調試目的的唯一列表。這也行不通!

我找到解決方案,在Object類型的DataLayer中添加新字段,並且它們未分配給任何字段。這些字段包含組合框的列表,並且我爲每個對象分別初始化這些列表。它很好用。但它仍然令我困惑,爲什麼以前的方法不起作用。我感覺這只是WPF中的錯誤。