开发者

Silverlight: DataGrid inside ListBox. Binding on DataGrid Column to a parent listbox's ItemsSource property. Silverlight

开发者 https://www.devze.com 2023-03-28 00:48 出处:网络
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

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=开发者_JAVA技巧"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");
        }
    }


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.


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消