我正在尝试在DataGridTemplateColumn中创建组合框,但它应该包含不同的值,具体取决于行。这是我的代码:
<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;
}
}
由于某种原因,前39行调用AllPlayers函数,然后从先前创建的列表中获取数据。我可以从调试信息中看到它(它在39次调用后停止打印)。并且组合框中的列表也不是唯一的。我不明白这种行为背后的逻辑。我需要为每一行调用AllPlayers。
答案 0 :(得分:0)
显示您对网格的绑定。我会让Players成为你绑定到网格的集合的公共属性。在39+的列表中,在那里建立AllPlayers。让我们假设你的39+名单是团队,并拥有名称,经理,城市,球员的属性。即使您获得了模板中构建的玩家,他们也不会直接与团队相关联(无需走可视树)。
答案 1 :(得分:0)
您的方法不正确..首先,您不应该信任数据网格虚拟化发生的顺序。因此,基于计数器的加载不同列表的方法不规律地发生。
当数据网格行被去虚拟化时,您的组合框变得可见并要求项目源并从Window.AllPlayers
属性获取它。但counter
的顺序将基于滚动而被搞砸。如果您突然滚动跳过几行范围,或者如果您使用延迟滚动,则counter
将始终是错误的。如果你来回滚动counter
将被搞砸(因为我没有看到任何减少计数器的代码)......
所以请不要使用这种方法。
现在你说你不想从单个项目加载列表。 counter
变量可能是指数据网格Index
中当前行的ItemsSource
。如果是这样,你至少可以使用多转换器。
Combobox 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;
}
.....
}
该代码仅用于说明目的,可能无法编译。
希望这有帮助。
答案 2 :(得分: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中的错误。