Silverlight:ListBox中的DataGrid。在DataGrid列中绑定到父列表框ItemsSource属性。 Silverlight的

时间:2011-08-11 17:36:24

标签: silverlight collections datagrid listbox itemssource

我对这个感到有些困惑。我有一个名为“AllProducts”的Collection,里面有一个名为“ProductGroups”的集合(分别对项目进行分组),里面包含一个名为“LineItems”(实际项目)的“Product”对象集合。

为了进行设置,我在ListBox的Items的itemtemplate中设置了一个带有DataGrid的ListBox。将列表框的ItemsSource设置为“ProductGroups”和DataGrid(在itemtemplate中)有一个指向LineItems的ItemsSource。

DataGrid包含列:
“选择” - 复选框和单选按钮
“图片” - 字符串
“姓名” - 字符串
“描述” - 字符串
“价格” - 字符串

“ProductGroup”集合每个组都有一个名为“IsListItem”的bool属性,它应该告诉我是否可以为该组选择多个或单个项目(因此DataGrid的第一列中的复选框和单选按钮) )。我希望checkbuttons和radiobuttons可见性属性绑定到“IsListItem”bool,我已经使用BoolToVisibility转换器设置了一个“IsInverted”属性来来回切换它们。

我遇到的问题是我想要包含复选框/ radiobuttons的DataGrid的第一列绑定到ProductGroups的IsLineItem(这是ListBox的ItemsSource。但是因为DataGrid的ItemsSource绑定到LineItems,DataGrid的DataContext设置为LineItems,我无法访问它之外的任何内容。

以下是一些有用的代码:

ListBox XAML:

<sdk:TabItem Header="Pmt" x:Name="Payment">
                <Canvas x:Name="PaymentRoot" DataContext="{Binding Products.ProductGroups}">
                    <Rectangle Height="418" Canvas.Top="-14" Width="560" Style="{StaticResource MappingRectangleBG}" />
                    <StackPanel Canvas.Left="20" Canvas.Top="20" Width="520" Height="360">
                        <ListBox x:Name="lstProductGroups"  ItemsSource="{Binding}" ItemTemplate="{StaticResource ProductListItem}" />      
                    </StackPanel>
                </Canvas>
            </sdk:TabItem>

ListBox ItemTemplate XAML:

<sdk:DataGrid x:Name="dgLineItems" ItemsSource="{Binding LineItems}">               
            <sdk:DataGrid.Columns>
                <sdk:DataGridTemplateColumn  Header="Select">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox Visibility="{Binding IsListType, Converter={StaticResource boolToVisibilityConverter}}" />
                                <RadioButton Visibility="{Binding IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}" GroupName="{Binding GroupName}"/>
                            </StackPanel>                               
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTemplateColumn  Header="Image">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="{Binding ImageUrl}" Height="50" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTextColumn Header="Item Name"
            Binding="{Binding Name}" />
            <sdk:DataGridTextColumn Header="Item Price"
            Binding="{Binding Price}" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>

    </StackPanel>
</DataTemplate>

和我的对象:

public class AllProducts
{

    public IEnumerable<ProductOptionGroup> ProductGroups;
}


public class ProductOptionGroup
{

    public string GroupName;

    public IEnumerable<Product> LineItems;

    public bool IsListType;
}


public class Product
{

    public int ID;

    public int OrdinalNumber;

    public string Name;

    public string Description;

    public Decimal Price;

    public string ImageUrl;

    public CartItemType Type;
}

(MichaelS):我尝试将它设置为Parent“PaymentRoot”Canvas'DataContext,但它没有为我做任何事情。这是我试过的:

<CheckBox Visibility="{Binding ElementName=PaymentRoot, Path=DataContext.IsListType, Converter={StaticResource boolToVisibilityConverter}}" />
<RadioButton Visibility="{Binding ElementName=PaymentRoot, Path=DataContext.IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}" GroupName="{Binding ElementName=PaymentRoot, Path=DataContext.GroupName}"/>

(MichaelS):这是我在VM中设置的方式: 私人AllProducts产品;

public AllProducts Products
    {
        get
        {
            return products;
        }
        set
        {
            //Products.ProductGroups[0].LineItems[0].
            products = value;
            RaisePropertyChanged("Products");
        }
    }

2 个答案:

答案 0 :(得分:0)

<强>更新 以下代码将无法使用,因为它是Silverlight 3时间段后期发现的已知问题。 使用column.GetCellContent(e.Row)在LoadingRow事件中设置Binding应该可以解决问题。

在这种特殊情况下,您希望能够这样做,因为dataGrid本身是另一个控件的dataTemplate。


试试这个: 将您的datagrid换成另一个Grid。将其命名,并将其用于元素绑定。 这段代码应该有效:

<StackPanel>
        <Grid x:Name="GridDataHolder">
            <sdk:DataGrid x:Name="dgLineItems" ItemsSource="{Binding LineItems}">
                <sdk:DataGrid.Columns>
                    <sdk:DataGridTemplateColumn  Header="Select">
                        <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource boolToVisibilityConverter}}" />
                                    <RadioButton Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}" GroupName="{Binding ElementName=GridDataHolder, Path=DataContext.GroupName}"/>
                                </StackPanel>
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellTemplate>
                    </sdk:DataGridTemplateColumn>
                    <sdk:DataGridTemplateColumn  Header="Image">
                        <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Image Source="{Binding ImageUrl}" Height="50" />
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellTemplate>
                    </sdk:DataGridTemplateColumn>
                    <sdk:DataGridTextColumn Header="Item Name"
        Binding="{Binding Name}" />
                    <sdk:DataGridTextColumn Header="Item Price"
        Binding="{Binding Price}" />
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
        </Grid>
    </StackPanel>

顺便说一句,我不确定绑定是否与公众成员合作,您可能需要将这些绑定成员更改为公共属性。

答案 1 :(得分:0)

终于搞定了!我最终要做的就是完全摆脱DataGrid,因为工具包中的很多控件似乎都有错误,即使通过Element Binding也无法绑定到外部。

我将DataGrid转换为一个ListBox,另一个DataTemplate用于LineItems,完全自定义它的外观,以实现与DataGrid类似的外观。

另外要注意:我首先尝试通过Element Binding绑定到DataTemplate外部的StackPanel,但它似乎有问题。所以我在DataTemplate的DataContext中设置了网格,然后我通过元素绑定将复选框和单选按钮绑定到父列表框的dataTemplate内的网格,这就行了!

以下是针对以后遇到同一问题的任何人的一些工作代码!:

<DataTemplate x:Key="LineItemsTemplate">
    <StackPanel Orientation="Horizontal">
        <StackPanel Height="100" Width="100">
            <StackPanel Height="40" Orientation="Vertical">
                <RadioButton Content="{Binding Name}" Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource boolToVisibilityConverter}}" GroupName="{Binding ElementName=GridDataHolder, Path=DataContext.GroupName}"/>
                <CheckBox Content="{Binding Name}" Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}"/>
            </StackPanel>
            <Image Source="{Binding ImageUrl}" Height="50" />
        </StackPanel>
        <TextBlock TextWrapping="Wrap" Text="{Binding Description}"/>
    </StackPanel>
</DataTemplate>
<DataTemplate x:Key="ProductListItem">
    <StackPanel x:Name="GridDataHolder">
            <TextBlock TextWrapping="Wrap" Text="{Binding GroupName}" VerticalAlignment="Top" d:LayoutOverrides="Width"/>
            <ListBox x:Name="lstProductGroups"  ItemsSource="{Binding LineItems}" ItemTemplate="{StaticResource LineItemsTemplate}">
            </ListBox>
    </StackPanel>
</DataTemplate>

<sdk:TabItem Header="Pmt" x:Name="Payment">
            <Canvas>
                <Rectangle Height="418" Canvas.Top="-14" Width="560" Style="{StaticResource MappingRectangleBG}" />
                <ScrollViewer Height="389" Width="545" x:Name="PaymentRoot" DataContext="{Binding Products.ProductGroups}">
                    <StackPanel Orientation="Vertical" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="500" HorizontalAlignment="Center">
                        <ListBox x:Name="lstProductGroups"  ItemsSource="{Binding}" ItemTemplate="{StaticResource ProductListItem}" />      
                    </StackPanel>
                </ScrollViewer>
            </Canvas>
        </sdk:TabItem>

感谢MichaelS的所有帮助!你让我走的正确!