Answered Databinding question

  • Friday, March 09, 2012 5:01 PM
     
      Has Code

    I have a list of objects with two properties. I want to produce table with a row for each object with  the data from the first property in the first column, and the second property in the second column.

    I'm trying to achieve this using a GridView as follows:-

    <GridView Grid.Row="1"  ItemsSource="{Binding Path=Instructions, Mode=TwoWay}" SelectionMode="None">
                                                    
                                                    <GridView.ItemTemplate>
                                                        <DataTemplate>                                                        
                                                            <Grid>
                                                                <Grid.ColumnDefinitions>
                                                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                                                </Grid.ColumnDefinitions>
                                                                <TextBlock Text="{Binding Path=Text}" />
                                                                <TextBlock  Grid.Column="1" Text="{Binding Path=Reason}"/>
    
                                                            </Grid>
                                                        </DataTemplate>
                                                    </GridView.ItemTemplate>
                                                   
                                                </GridView>

    but this just results in each row having different size columns. I can get around this by providing a size for the column widths, but I want the screen to work on different resolutions so I would rather do it the "correct" way assuming there is one!

    Thanks

    Ross

All Replies

  • Friday, March 09, 2012 5:19 PM
     
     

    There's no way to know how big the text is until it's rendered, so I think your best option here would be to use relative sizing, say 1* and 2*? Ideally, you'd like users to be able to re-size the widths as necessary. GridSplitter isn't in the Metro toolkit, but if you look at this thread http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/ae4a798a-f3c1-423c-8d36-01254e7aa8e6 Filip Skakun posts a link to a replacement he wrote to provide that functionality.


    Rebecca M. Riordan

  • Friday, March 09, 2012 6:16 PM
     
     

    I think that the main problem is that every individual Grid has its own width (not the columns, but the whole Grid). Maybe it helps to add HorizontalAlignment="Stretch" to the Grid... Otherwise you should use another container as data template.

  • Monday, March 12, 2012 9:42 AM
     
     

    I think this is the problem - each grid gets it's own width. I can't think of a better container to use however?

    So far can't get HorizontalAlignment to fix the issue.

  • Monday, March 12, 2012 10:19 AM
     
     

    You can try to have the grid as ItemsPanelTemplate, instead of ItemTemplate.

    This way, every rows will have the same column size ?


    - NV

  • Monday, March 12, 2012 10:40 AM
     
      Has Code

    Apparently the default container of a gridview row is a left-aligned listview item. Here's how to override that:

    <GridView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
        </Style>
    </GridView.ItemContainerStyle>

  • Monday, March 12, 2012 10:56 AM
     
      Has Code

    I think this is probably the correct route but I can't get this to work as the DataTemplate needs a container and I'm not sure what the correct template would be:

    <GridView.ItemTemplate>
        <DataTemplate>                                                           
                    <TextBlock Text="{Binding Path=Text}"  TextWrapping="Wrap"/>
                    <TextBlock Grid.Column="1" Text="{Binding Path=Reason}" TextWrapping="Wrap"/>                                                           
            </DataTemplate>
    </GridView.ItemTemplate>
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="750"></ColumnDefinition>
                    <ColumnDefinition Width="750"></ColumnDefinition>
                </Grid.ColumnDefinitions>
            </Grid>
    
            </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    I'm pretty new to WPF!

  • Monday, March 12, 2012 12:30 PM
     
     

    This is a solution, but it's heavy.

    You should try an other way to display your data, like a Stackpanel for each of your column (for each field of your object that you want to display) ? This will do the job if your infos are inline.


    - NV

  • Tuesday, March 13, 2012 8:35 AM
    Moderator
     
     Answered Has Code

    Hi RossDargan,

    This will still be pretty complicated if you use ItemsPanelTemplate because it require split each cell into a separate item in the itemssource. And it's not easy to set Grid.Columns for the containers.

    I agree with Diederik Krols about why your original code doesn't work. The default values of alignment property are different in Metro Style app compare to WPF. You can try the following code along with your original code to solve the problem.

                <GridView.ItemContainerStyle>
                    <Style TargetType="GridViewItem">
                        <Setter Property="HorizontalAlignment" Value="Stretch"/>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    </Style>
                </GridView.ItemContainerStyle>
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel HorizontalAlignment="Stretch"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

  • Tuesday, March 13, 2012 8:47 AM
     
     
    I've done something similar with a ListView instead: <ListView HorizontalAlignment="Left" VerticalAlignment="Top" Height="282" Width="562" x:Name="listView"> <ListView> <DataTemplate> <StackPanel Orientation="Horizontal" > <TextBox Text="{Binding ID}"/> <TextBox Text="{Binding Description}"/> </StackPanel> </DataTemplate> </ListView> <ListView.ItemContainerStyle> <Style TargetType="ItemsControl"> <Setter Property="Height" Value="36" /> <Setter Property="Padding" Value="0" /> <Setter Property="Margin" Value="0" /> </Style> </ListView.ItemContainerStyle> </ListView>
  • Tuesday, March 13, 2012 8:53 AM
     
     
    Great, cant edit my post, and the formatting option are not clickable in IE10, sorry.
  • Tuesday, March 13, 2012 9:25 AM
     
     

    I suspect that this works because you have set an absolute hight. I want Column A to be 50% of the width, and Column B to be 50% - that's what I'm struggling to achieve.

    Thanks

    Ross

  • Tuesday, March 13, 2012 9:37 AM
     
      Has Code

    This shows the result of the suggested change - it appears to set the second column correctly but because the text in the first row, second column doesn't wrap around it doesn't quite work.

    Here is my current code as it stands

    <GridView Grid.Row="1" HorizontalAlignment="Stretch"  ItemsSource="{Binding Path=Instructions, Mode=OneWay}" SelectionMode="None" IsSwipeEnabled="False" IsItemClickEnabled="False">
        <GridView.ItemContainerStyle>
            <Style TargetType="GridViewItem">
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </GridView.ItemContainerStyle>
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel HorizontalAlignment="Stretch"/>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
        <GridView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Path=Text}" TextWrapping="Wrap" />
                    <TextBlock  Grid.Column="1" Text="{Binding Path=Reason}" TextWrapping="Wrap"/>
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

    I'm getting to the point where I'm assuming this isn't possible without setting an absolute width for the columns.

    Thanks

    Ross

  • Thursday, March 15, 2012 3:40 AM
    Moderator
     
     Answered Has Code

    Hi Ross,

    Sorry for the late reply.

    Try to also disable the horizontal scrolling of the gridview in your scenario. It mess up the layout when you want to arrange the current space and don't want to scroll horizontally.

    <GridView ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>

    Best regards,

    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

  • Monday, March 26, 2012 5:38 AM
     
      Has Code

    I have a list of objects with two properties. I want to produce table with a row for each object with  the data from the first property in the first column, and the second property in the second column.

    I'm trying to achieve this using a GridView as follows:-

    <GridView Grid.Row="1"  ItemsSource="{Binding Path=Instructions, Mode=TwoWay}" SelectionMode="None">
                                                    
                                                    <GridView.ItemTemplate>
                                                        <DataTemplate>                                                        
                                                            <Grid>
                                                                <Grid.ColumnDefinitions>
                                                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                                                </Grid.ColumnDefinitions>
                                                                <TextBlock Text="{Binding Path=Text}" />
                                                                <TextBlock  Grid.Column="1" Text="{Binding Path=Reason}"/>
    
                                                            </Grid>
                                                        </DataTemplate>
                                                    </GridView.ItemTemplate>
                                                   
                                                </GridView>

    but this just results in each row having different size columns. I can get around this by providing a size for the column widths, but I want the screen to work on different resolutions so I would rather do it the "correct" way assuming there is one!

    Thanks

    Ross

    Hai Ross, Could you please post your complete code or send code to this sivaprasad.varri87@hotmail.com .I want to know , how to bind data in gridview in metro style apps.