Silverlight:ListBox 内的 DataGrid。将 DataGrid 列绑定到父列表框的 ItemsSource 属性。银光

发布于 2024-11-29 06:44:59 字数 4590 浏览 1 评论 0原文

我对这个有点困惑。我有一个名为“AllProducts”的集合,其中有一个名为“ProductGroups”(分别对项目进行分组)的集合,其中包含一个名为“LineItems”(实际项目)的“Product”对象的集合。

为了进行设置,我在列表框项目的项目模板内设置了一个带有 DataGrid 的列表框。将列表框的 ItemsSource 设置为“ProductGroups”,并且 DataGrid(在项目模板中)具有指向 LineItems 的 ItemsSource。

DataGrid 包含列:
“选择”——复选框和单选按钮
“图像”——字符串
“名称”——字符串
“描述”——字符串
“Price” -- string

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

我遇到的问题是,我希望包含复选框/单选按钮的 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):我尝试将其设置为父“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):这是它在我的虚拟机中的设置方式: 私人 AllProducts 产品;

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

I'm a little puzzled with this one. I have a Collection called "AllProducts", which has a collection inside called "ProductGroups" (to group items separately) which inside contain a collection of "Product" objects called "LineItems" (the actual items).

To set this up, I have set a ListBox with a DataGrid inside the itemtemplate for the ListBox's Items. Setting the ItemsSource of the listbox to "ProductGroups" and the DataGrid(In the itemtemplate) has an ItemsSource pointing to LineItems.

The DataGrid contains Columns:
"Select" -- A checkbox and a radiobutton
"Image" -- string
"Name" -- string
"Description" -- string
"Price" -- string

The "ProductGroup" collection has a bool property called "IsListItem" per group, which is supposed to tell me if you can select multiple or a single item for that group (hence the checkbox and radiobutton in the first column of the DataGrid). I want the checkbuttons and radiobuttons visibility property to be bound to "IsListItem" bool which I have already set up with a BoolToVisibility converter with an "IsInverted" property to switch them back and forth.

The problem that I'm running into is that I want the first column of the DataGrid which contains the checkboxes/radiobuttons to be bound to the IsLineItem of ProductGroups (which is the ListBox's ItemsSource. But Since the DataGrid's ItemsSource is bound to LineItems, the DataContext of the DataGrid is set to LineItems and I can't access anything outside of it.

Here's some code to help:

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>

And my Objects:

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): I tried setting it to the Parent "PaymentRoot" Canvas' DataContext but it isn't doing anything for me. Here is what I tried:

<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): here's how it's set up in my VM:
private AllProducts products;

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

才能让你更想念 2024-12-06 06:44:59

更新:
以下代码将不起作用,因为这是在 Silverlight 3 时间范围后期发现的已知问题。
使用 column.GetCellContent(e.Row) 在 LoadingRow 事件中设置 Binding 应该可以解决该问题。

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


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

<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>

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

Update:
The below code won't work since it's a known issue that was discovered late in the Silverlight 3 timeframe.
Setting the Binding in the LoadingRow event using column.GetCellContent(e.Row) should solve the issue.

In this particular case , you want be able to do that since the dataGrid itself is a dataTemplate of another control.


Try this:
Wrap your datagrid with another Grid. Name it, and use it for the element binding.
This code should work:

<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>

By the way, i'm not sure if binding works with public members, you may need to change those binded members to public properties.

瑶笙 2024-12-06 06:44:59

终于修好了!我最终要做的就是完全摆脱 DataGrid,因为工具包中的许多控件似乎都存在即使通过元素绑定也无法绑定到外部的错误。

我将 DataGrid 变成了一个 ListBox,并使用另一个用于 LineItems 的 DataTemplate 完全自定义了它的外观,以实现与 DataGrid 类似的外观。

另请注意:我首先尝试通过元素绑定绑定到 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 的所有帮助!你让我走上了正确的道路!

Finally got it fixed! What I had to end up doing was getting rid of the DataGrid altogether because a lot of controls from the toolkit seem to have that bug not being able to bind outside even through Element Binding.

I turned the DataGrid into a ListBox with another DataTemplate for the LineItems completely customizing the look of it to achieve a similar look that I had with the DataGrid.

Also to note: I tried at first binding to the StackPanel outside of the DataTemplate through Element Binding but it seemed to have a problem with that. So I set the grid inside the DataTemplate's DataContext and then I made the checkbox and radiobutton bound to the grid inside the Parent Listbox's dataTemplate through element binding and that did the trick!

Here is some working code for anybody who runs into this same issue later on!:

<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>

Thanks MichaelS for all your help! You got me going the right way!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文