0

我正在尝试在 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。

4

3 回答 3

0

显示您对网格的绑定。我会让 Players 成为您绑定到网格的集合的公共属性。在 39+ 列表的 ctor 中,在那里构建 AllPlayers。让我们假设您的 39 人以上的列表是团队,并且具有名称、经理、城市、球员的属性。即使您在模板中构建了球员,他们也不会直接与球队相关联(无需遍历视觉树)。

于 2011-10-12T22:15:02.660 回答
0

您的方法不正确..首先您不应该相信数据网格虚拟化发生的顺序。因此,加载不同列表的基于计数器的方法发生不规律。

当数据网格行被去虚拟化时,您的组合框变得可见并需要项目源并从Window.AllPlayers属性中获取它。counter但是基于滚动的顺序将被搞砸。如果您突然滚动跳过几行范围,或者如果您使用延迟滚动,counter则总是错误的。如果你来回滚动,counter就会搞砸(因为我没有看到任何减少计数器的代码)......

所以底线是请不要使用这种方法。

现在您说您不想从单个项目加载列表。该counter变量可能是指Index数据网格中的当前行ItemsSource。如果是这样,您至少可以使用多转换器。

组合框 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;
    }
    .....
}

该代码仅用于说明目的,可能无法编译。

希望这可以帮助。

于 2011-10-13T06:15:36.937 回答
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 中的错误。

于 2011-10-13T08:13:09.300 回答