How to make Buttons in ListBox all the same width - wpf

My WPF application contains a window that has a single ListBox in it. The View Model for the window contains an ObservableCollection of DomainViewModel objects.
The window defines the following DataTemplate:
<DataTemplate x:Key="DomainTemplate" DataType="DomainViewModel">
<Border BorderBrush="{Binding Converter={StaticResource BrushConverter}, Path=IsSelected}"
BorderThickness="2"
Name="SelectedBorder">
<Button Click="SelectDomain_Click"
Content="{Binding Path=Name}"
FontSize="16"
FontWeight="Bold"
Height="60"
HorizontalAlignment="Stretch" />
</Border>
</DataTemplate>
And here's the ListBox's declaration:
<ListBox FontSize="16"
FontWeight="Bold"
Grid.Row="2"
ItemsSource="{Binding Path=Domains}"
ItemTemplate="{StaticResource DomainTemplate}"
Name="DomainListBox" />
When the window renders, each button is exactly wide enough to display the text in its Content property. But that's not what I want. I want each button to be the width of the ListBox, which is going to vary with the width of the window itself.
How do I get the Buttons to keep their width set to the ListBox's width?

<ListBox HorizontalContentAlignment="Stretch"
.../>

Related

Border that bulges near mouse pointer

I have a ListView populated with ListViewItems, like navigation bar style menu options.
I would like to create the effect of the ListViewItem border "bulging" like in the Mail application on Win10 as shown in this picture
The border "bulges" (fisheye?) as the mouse moves left and right along the ListViewItem. It's a nice effect that I'd like to replicate but am struggling to even get started on how to tackle this.
My list items are bound to a content control which is templated with a ControlTemplate. The ItemsControl ItemTemplate is a DataTemplate containing an image and a Textbox wrapped inside a button control, like this .... (although I suspect how it's created is probably not relevant to my question)
<ContentControl Content="{Binding Path=MenuModel.AllMenuItems}"
x:Name="menuCtrl1"
Template="{StaticResource MenuListItemControlTemplate}"
VerticalAlignment="Top" />
...
<ControlTemplate x:Key="MenuListItemControlTemplate" TargetType="ContentControl">
<Border Background="Transparent" >
<ScrollViewer Margin="{StaticResource DefaultNoMargin}" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{TemplateBinding Content}"
ItemTemplate="{StaticResource MenuListItemDataTemplate}" />
</ScrollViewer>
</Border>
</ControlTemplate>
...
<DataTemplate x:Key="MenuListItemDataTemplate" DataType="local:SingleMenuItem">
<Button Command="{Binding MenuCommand}" Style="{StaticResource MenuButtonStyle}" >
<StackPanel Orientation="Horizontal" >
<Image Source="{Binding MenuIconSource}" Style="{StaticResource MenuItemImage}" />
<TextBox Text="{Binding DisplayText}" Style="{StaticResource MenuItemStyle}" />
</StackPanel>
</Button>
</DataTemplate>
Any tips on how to achieve it or even where to start would be gratefully received.

cannot display the slider of a scrollviewer

I can't get the slider for a scrollviewer to display. I have a listbox in a wrappanel. The listbox has a list of numbers. The list can be long enough to extend off of the bottom of the screen, so a scrollviewer is needed, but no matter how I set scrollviewer properties, or even if I put the listbox inside a scrollviewer inside the wrappanel, the slider doesn't appear. What am I doing wrong? Here's the XAML:
<WrapPanel Grid.Row="5" Grid.ColumnSpan="2">
<ListBox x:Name="lstBxCollisions"
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="auto" Width="auto"
ItemsSource="{Binding MainWindow.lstBxCollisions}"
ScrollViewer.VerticalScrollBarVisibility="Auto"/>
<FlowDocumentReader Grid.Row="5" Grid.Column="1" Document="{Binding SingleAccidentFlowDocument}">
</FlowDocumentReader>
</WrapPanel>
Since your ListBox is inside WrapPanel, all its sizes are selected automatically and it begins to expand as the content size increases.
If you want it to appear ScrollBar, you need to fix the size of the ListBox by setting the actual height and width.
For example:
<WrapPanel Grid.Row="5" Grid.ColumnSpan="2">
<ListBox x:Name="lstBxCollisions"
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="100" Width="100"
ItemsSource="{Binding MainWindow.lstBxCollisions}"
ScrollViewer.VerticalScrollBarVisibility="Auto"/>
<FlowDocumentReader Grid.Row="5" Grid.Column="1" Document="{Binding SingleAccidentFlowDocument}">
</FlowDocumentReader>
</WrapPanel>

WPF Popup inside a DataTemplate

I need a WPF Popup inside a DataTemplate, something like this:
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Collection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox Name="MyTextboxBrief" Text="{Binding TextBrief}"/>
<Popup PlacementTarget="{Binding ElementName=MyTextboxBrief}" Placement="Center">
<TextBox Name="MyTextboxVerbose" Text="{Binding TextVerbose}"/>
</Popup>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
But, this Popup should behave like this:
it must scroll together with relevant ItemsControl item
when app window is minimized - it shouldn't stay visible on desktop
it will be taller than ItemsControl, its content mustn't be clipped, but it mustn't change ItemsControl height
it will be wider than relevant ItemsControl item - but it shouldn't shift other ItemsControl items to the left or to the right
I have a strong feeling that I should somehow use ComboBox template - but I don't understand how to get it's Popup behavior
I don't think that Popup will help you here, nor ComboBox. See if this helps you any further:
<DataTemplate>
<Grid>
<TextBox Name="MyTextboxBrief" Text="{Binding TextBrief}" />
<!-- You might want to bind visibility against
some kind of property -->
<Canvas >
<Canvas.RenderTransform>
<!--In case you want to move-->
<TranslateTransform Y="-5" />
</Canvas.RenderTransform>
<Border Width="100" Height="20" Background="Black">
<TextBlock Text="Test" />
</Border>
</Canvas>
</Grid>
</DataTemplate>

VerticalAlignment="Stretch" stretches out of my container

I have a parent container that is used to hold all of my user controls. The issue is that I use VerticalAlignment="Stretch" to stretch contents to the full height and get a vertical scroll bar the user control gets stretched too much. The vertical scrollbar appears but there is no way to scroll. I know this because the down arrow for the scroll bar isn't visible.
I have <ContentControl Content="{Binding Workspace}" /> which is where a variety of controls can be assigned. For example, here is the XAML that is not working property in regards to stretching.
<StackPanel>
<TextBlock Text="{Binding FoundCount}" FontSize="13" Foreground="#666" Margin="0 0 0 8" />
<ScrollViewer VerticalAlignment="Stretch">
<TreeView
ItemsSource="{Binding Listing}"
Grid.Row="1"
BorderThickness="0"
VirtualizingStackPanel.IsVirtualizing="True" />
</ScrollViewer>
</StackPanel>
I only want to the TreeView to stretch and display a vertical scrollbar.
Any ideas?
I suspect the height of the StackPanel is not contrained so it grows to accomodate the ScrollViewer. You can check this by putting a border on the StackPanel.
<Border>
<StackPanel>
<TextBlock Text="{Binding FoundCount}" FontSize="13" Foreground="#666" />
<ScrollViewer VerticalAlignment="Stretch">
<TreeView ItemsSource="{Binding Listing}" BorderThickness="0"
VirtualizingStackPanel.IsVirtualizing="True" />
</ScrollViewer>
</StackPanel>
</Border>

WPF - How to stop TextBox from autosizing?

I have a textbox in my visual tree as follows..
Window
Grid
ListBox
ItemTemplate
DataTemplate
Grid
Grid
Textbox...
The textbox is defined as..
<TextBox Height="Auto"
Text="{Binding Path=LyricsForDisplay}"
MinHeight="50"
MaxHeight="400"
Visibility="Visible"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
AllowDrop="False"
TextWrapping="WrapWithOverflow">
</TextBox>
When long text is added to the bound variable (LyricsForDisplay) all of the items in the listbox expand their textboxes/grids width's to allow for the entire string to be seen if you use the scrollbar on bottom that appears...
What I would like to do is make it so the boxes/grids only resize if the user stretches the window .. NOT when a long text is entered (it could just wrap around..)
Does anyone know how to obtain the functionality?
The following works:
<ListBox Name="ListBox1"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid>
<TextBox TextWrapping="Wrap"></TextBox>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Notice the use of ScrollViewer.HorizontalScrollBarVisibility="Disabled" and TextWrapping="Wrap".
Unfortunately, the regular TextBox doesn't allow autoresize to fit the parent but NOT autoresize when the text doesn't fit.
To solve this problem, you can use a custom TextBox that reports a desired (0, 0) size. It's an ugly hack, but it works.
In your .xaml.cs file:
public class TextBoxThatDoesntResizeWithText : TextBox
{
protected override Size MeasureOverride(Size constraint)
{
return new Size(0, 0);
}
}
Then, in your .xaml file:
<Window x:Class="YourNamespace.YourWindow"
...
xmlns:local="clr-namespace:YourNamespace">
...
<local:TextBoxThatDoesntResizeWithText Height="Auto"
Text="{Binding Path=LyricsForDisplay}"
MinHeight="50"
MaxHeight="400"
Visibility="Visible"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
AllowDrop="False"
TextWrapping="WrapWithOverflow">
</local:TextBoxThatDoesntResizeWithText>
...
</Window>
Something needs to contrain the horizontal width available to the TextBoxes, in this case you want to stop the ListBox from growing horizontally indefinitely:
<ListBox HorizontalScrollBarVisibility="Disabled"
two change the code:
1- add border tag with your grid.column and grid.row size that you are neads.
2- width and height of textbox set to it.
sample:
<Border x:Name="b" Margin="5"/>
<TextBox Height="Auto"
Text="{Binding Path=LyricsForDisplay}"
MinHeight="50"
Width="{Binding ActualWidth, ElementName=b}"
Height="{Binding ActualHeight, ElementName=b}"
Visibility="Visible"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
AllowDrop="False"
TextWrapping="Wrap">
</TextBox>
Try setting the the MaxWidth Property in Your Textbox
<TextBox Height="Auto" Text="{Binding Path=LyricsForDisplay}" MinHeight="50" MaxHeight="400" Visibility="Visible" VerticalScrollBarVisibility="Auto" MaxWidth="100" IsReadOnly="True" AllowDrop="False" TextWrapping="WrapWithOverflow"> </TextBox>

Resources