Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: Set ListViewItem from textblock in the Listview within a DataTemplate

I have a Windows Phone 8.1 project with a ListView that has it's itemssource filled from c# code behind. It works but i end up with empty spaces between single line textblocks. I've tried setting heights on the textblock, a grid it sits within, the listview itself. I tried setting an ItemContainerStyle with binding the height to the height of the textblock but it doesn't work.
If I set the text of the TextBlock to the Actual Height binding I get 0 so I must be doing something wrong. I'm pretty sure it has something to do with the height of the ListViewItems but since they are populated from code I can't figure out how to make them do what I want. I also tried switching to a ItemsControl for the list but it doesn't seem to scroll and work as well. Here is the XAML of the Listview:

<ListView x:Name="TheList" IsHoldingEnabled="True"
                      ItemsSource="{Binding items}"
                      Loaded="WhenListViewBaseLoaded"
                      ContinuumNavigationTransitionInfo.ExitElementContainer="True"
                      IsItemClickEnabled="True">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Height" Value="{Binding ElementName=txtBibleText, Path=ActualHeight}"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="ItemTemplateGrid" Holding="ListViewItem_Holding" Background="Blue">
                        <FlyoutBase.AttachedFlyout>
                            <MenuFlyout>
                                <MenuFlyoutItem Text="Share"
                                                Click="ShareFlyoutItem_Click" />
                                <MenuFlyoutItem Text="Add to Sharing"
                                                Click="AddSharingFlyoutItem_Click" />
                            </MenuFlyout>
                        </FlyoutBase.AttachedFlyout>
                        <Grid x:Name="gridText">
                            <TextBlock x:Name="txtBibleText" 
                                   FontSize="{Binding TheFontSize}"
                                   Grid.Column="1"
                                   VerticalAlignment="Top"
                                   HorizontalAlignment="Left"
                                   TextWrapping="Wrap"
                                   Margin="0,0,0,0" FontFamily="Global User Interface">
                            <Run Text="{Binding VerseNumber}"/>
                            <Run Text="{Binding BibleText}"/>
                            </TextBlock>
                        </Grid>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

Code behind that populates the ListView:

XDocument loadedData = XDocument.Load(TranlationFilePath);
            var data = from query in loadedData.Descendants("testament").Descendants("book").Descendants("chapter").Descendants("verse")
                       where (string)query.Parent.Parent.Parent.Attribute("name") == GetTestament
                       where (string)query.Parent.Parent.Attribute("name") == GetBibleBook
                       where (string)query.Parent.Attribute("number") == GetChapter
                       select new BibleLoad
                       {
                           VerseNumber = (string)query.Attribute("number"),
                           BibleText = (string)query.Value.ToString(),
                           TheFontSize = FontSize
                       };
            TheList.ItemsSource = data;

Thank you for your time. This is my first time posting a question so hopefully I did it right. I have searched and searched and experimented for quite awhile.

enter image description here

After editing the XML and making a record short. With verse 8 edited

With turning off the text wrapping.

enter image description here

With wrapping back on, height set to 20 and minheight set to 31. enter image description here

MinHeight to 20 wrapping on:

enter image description here

like image 795
Jason Prahl Avatar asked Nov 11 '22 02:11

Jason Prahl


1 Answers

The extra space comes from the ListViewItem template for the ItemContainerStyle. The default template includes space not only for the ItemTemplate but also for adornments such as checkboxes used to mark selection. Note the CheckboxContainers' Rectangle's Height of 25.5 and the SelectedCheckMark's Height of 34.

<Grid x:Name="CheckboxContainer">
    <Grid.RenderTransform>
        <TranslateTransform x:Name="CheckboxContainerTranslateTransform" X="{ThemeResource ListViewItemContentOffsetX}"/>
    </Grid.RenderTransform>
    <Rectangle x:Name="NormalRectangle" Fill="{ThemeResource CheckBoxBackgroundThemeBrush}" Height="25.5" Stroke="{ThemeResource CheckBoxBorderThemeBrush}" StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}" Width="25.5"/>
    <Path x:Name="CheckGlyph" Data="M0,123 L39,93 L124,164 L256,18 L295,49 L124,240 z" Fill="{ThemeResource CheckBoxForegroundThemeBrush}" FlowDirection="LeftToRight" HorizontalAlignment="Center" Height="17" IsHitTestVisible="False" Opacity="0" Stretch="Fill" StrokeThickness="2.5" StrokeLineJoin="Round" VerticalAlignment="Center" Width="18.5"/>
</Grid>

and

<Border x:Name="SelectedBorder" BorderBrush="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}" BorderThickness="{ThemeResource GridViewItemMultiselectBorderThickness}" IsHitTestVisible="False" Opacity="0">
    <Grid x:Name="SelectedCheckMark" HorizontalAlignment="Right" Height="34" Opacity="0" VerticalAlignment="Top" Width="34">
        <Path x:Name="SelectedEarmark" Data="M0,0 L40,0 L40,40 z" Fill="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}" Stretch="Fill"/>
        <Path x:Name="SelectedGlyph" Data="M0,123 L39,93 L124,164 L256,18 L295,49 L124,240 z" Fill="{ThemeResource ListViewItemCheckThemeBrush}" FlowDirection="LeftToRight" HorizontalAlignment="Right" Height="14.5" Margin="0,1,1,0" Stretch="Fill" VerticalAlignment="Top" Width="17"/>
    </Grid>
</Border>

If you don't need the selection behavior you can strip the ItemContainerStyle to just the pieces you need so it doesn't have to make space for adornments that aren't relevant to your app. If you do need selection you can move or resize the selection checks so they'll fit with your design.

You can generate the default ItemContainerStyle template by selecting your ListView in the designer, right clicking and chosing Edit Additional Templates.Edit Generated Item Container (ItemContainerStyle) Edit a copy... enter image description here

You can then edit down the adornment Heights as needed.

like image 105
Rob Caplan - MSFT Avatar answered Nov 14 '22 22:11

Rob Caplan - MSFT