WPF - Can't right-align a TextBlock when using StringFormat - wpf

I have a TextBlock within a GridViewColumn. I format to currency using StringFormat. This causes the field to be left aligned. I can't get it right aligned. Tried HorizontalAlignment and TextAlignment but nothing works.
<TextBlock HorizontalAlignment="Right" Text="{Binding Path=Amount, StringFormat={}{0:€ # ##0}}" />
<TextBlock TextAlignment="Right" Text="{Binding Path=Amount, StringFormat={}{0:€ # ##0}}" />
If I do this from this post, it works but right aligns all columns. I want numbers right aligned, dates centre and text left.
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Right" />
</Style>
</ListView.Resources>
Any clues please?

Set HorizontalContentAlignment to Stretch. This will work:
<ListView>
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Right"
Text="{Binding Path=Amount, StringFormat={}{0:€ # ##0}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>

Change your resource to HorizontalContentAlignment to Stretch, this will allow the contents of each cell in the ListView to take up the entire space. Then your HorizontalAlignment attributes will work.

Related

Disable ListView selection and hover

Usually I can disable ListView selection doing like this thread suggests - or something similar where you set the ItemContainerStyle.
However I have this ListView that is defined like this:
<ScrollViewer>
<ListView ItemsSource="{Binding List, Mode=OneWay}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumnHeader Style="{StaticResource header}"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<!-- Some data -->
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridViewColumn>
...
</GridView>
</ListView.View>
</ListView>
</ScrollViewer>
And if I try to specify the ItemContainerStyle - the data in the list just disappears.
Giving the above ListView, how would I proceed just to removed the selection?
Can you try this ItemContainerStyle? This basically will not pick up any input events.
<ListView ItemsSource="{Binding List, Mode=OneWay}">
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>

How to bind button inside listview

I cant bind button inside listview to the GoToTask property, every other binding, include second button in the grid is work well.
<Grid>
<ListView ItemsSource="{Binding Projects}" SelectedItem="{Binding SelectedProject, Mode=TwoWay}" Grid.Row="1">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Go">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Go" Command="{Binding Path=GoToTasks, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Height="20" Width="50" HorizontalAlignment="Right" Command="{Binding GoToTasks}" Content="Go"/>
</Grid>
Everything is inside UserControl.
What is wrong?
GridViewColumn is not part of VisualTree and therefore you are not allowed to use FindAncestor.
Similar here. Try ElementName, as far as I remember it uses LogicalTree.

Is there any simplier/better way to auto-size the content of one-column ListView?

Alright, sorry for my english in advance, here what I need:
I got a ListView in XAML (WPF) where there items is located and what I need is that items to have the width equal to the ListView's width.
So far, I did this:
<ListView Name="lvFiles" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid Width="{Binding ElementName="lvFiles", Path=ActualWidth}">
<!-- All the controls inside I need to present an item -->
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
But as it turned out, the ListView items become clipped on the right when the vertical scrollbar appears. And it appears when the total height of all items exceeds the ListView.ActualHeight, so I needed to user bindings more complex and hence more complicated.
Also, my items, while I was spending hours to solve the problem, my items sometimes were clipped on the right with no obvious reason.
So I came up with this:
<ListView Name="lvFiles" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.View>
<GridView>
<GridViewColumn Width="{Binding ElementName=lvFiles, Path=ActualWidth}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Decorator Width="{Binding RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=ListViewItem},
Path=ActualWidth}">
<Grid Margin="0,0,18,0">
<!-- All the controls inside... -->
</Grid>
</Decorator>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
It solved clipping problem and also it solved the problem with one-columned ListViewItem auto-size. But now it seems to be not the simpliest way. Is there any such?
You're not using a header so you can use ListView directly without using GridView. As for the width, don't adjust the content width, but adjust the ListViewItem width.
Here's an example:
<Style x:Key="singleListViewItemStyle"
BasedOn="{StaticResource {x:Type ListViewItem}}"
TargetType="{x:Type ListViewItem}">
<Setter Property="Width"
Value="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type VirtualizingStackPanel}}}" />
</Style>
If you do not have an existing style targeting ListViewItem or do not want to inherit from it, you can remove BasedOn="{StaticResource {x:Type ListViewItem}}".
AncestorType={x:Type VirtualizingStackPanel} is used because by default, that is what ListView displays its content in. If you have your own ListView theme, then see the following example:
<ListView Name="myListView"
ItemContainerStyle="{StaticResource ResourceKey=singleListViewItemStyle}"
ItemsSource="{Binding Path=MyItems}"
SelectedItem="{Binding Path=MySelectedItem, Mode=TwoWay}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<!--Your favorite controls-->
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is the link for a demo project I made for you. You can also see my other controls.
I hope this helps.

Listview Automatic Scrolling using MVVM

I'm trying to implement automatic scrolling of a Listview using MVVM. I know that you can update the listview by calling ScrollIntoView but that requires Code Behind which I'm trying to avoid.
I've bound my ListView's ItemSource to an ObservableCollection and would like the Listview to automatically scroll down to the newest item added to the log.
<ListView ItemsSource="{Binding Log}"
SelectedIndex="{Binding SelectedLine}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Row="1">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel>
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Type" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}" HorizontalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
MVVM and Attached Behaviors go hand in hand. You can use attached behavior to scroll to new item after the ObservableCollection.Add() takes place...
This article is a good example that tries to bring a tree view item into scroll view while sticking to MVVM.

Make WPF ComboBoxes fill a whole column width

I'm having problems making a ComboBox stretch to fill the whole column width in a GridViewColumn. It should also resize when the column is resized.
In the following example I have a StackPanel with a ComboBox inside. This is set to stretch and will in fact stretch to fill the StackPanel width.
Then I add a ListView with one column, containing a StackPanel with a ComboBox. Both the StackPanel and the ComboBox are set to stretch, but they don't. I use background colors to identify the size of the StackPanels, and there is no red unless I set a width or add elements to the ComboBox such that it needs more width.
I also tried playing around with the HorizontalContentAlignment property without success.
<StackPanel Height="59" Margin="45,12,38,0" VerticalAlignment="Top" Background="Green">
<ComboBox HorizontalAlignment="Stretch" />
</StackPanel>
<ListView x:Name="MyListView" Margin="0,106,0,0">
<ListView.View>
<GridView>
<GridViewColumn Header="Num" Width="70">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Background="red" Orientation="Horizontal" HorizontalAlignment="Stretch">
<ComboBox HorizontalAlignment="Stretch" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListViewItem></ListViewItem>
</ListView>
Try setting the Style of the ListViewItem. I also removed your StackPanel.
<ListView x:Name="MyListView" Margin="0,106,0,0">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Num" Width="170">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListViewItem></ListViewItem>
</ListView>

Resources