How to create empty expanding grid col in expander header - wpf

I'm trying to create a custom expander header that will show one text box on the left, and several others on the right, and as the windows grows horizontally the left and right text blocks get further apart. It feels like this should work, but everything stays left justified.
<Expander.Header>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" Name="LeftJustifiedCol" ></ColumnDefinition>
<ColumnDefinition Width="*" Name="EmptySpaceCol" ></ColumnDefinition>
<ColumnDefinition Width="Auto" Name="RightJustifiedCol" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="5,0,5,0" Text="{Binding GroupByValue}"></TextBlock>
<DockPanel Grid.Column="2" HorizontalAlignment="Right">
<TextBlock DockPanel.Dock="Right" Margin="5,0,5,0" Text="Net: $0.00"></TextBlock>
<Button DockPanel.Dock="Right" Margin="5,0,5,0" Width="Auto" Name="DeleteEntityBtn" Click="DeleteEntityBtn_Click" >Del</Button>
</DockPanel>
</Grid>
</Expander.Header>
any suggestions?

I am guessing WPF isn't rendering the middle column because it contains no content, so it takes up no space in the UI. Perhaps a DockPanel with LastChildFill="False" would work better than a Grid

Related

buttons are being cut off of the page

I have two sets of controls within a row. They are both in their respective stack panels. The first is aligned to the left and the second is aligned to the right. It looks good, except that the controls on the right are cut off by the application window. I can stretch out the window with my mouse and it looks fine, but it would be better if the buttons would just push in as the application window collapses.
Here is the xaml:
<Grid Grid.Row="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Orientation="Horizontal"
HorizontalAlignment="Left">
<Label Content="Instant Message Text"
Margin="5"></Label>
<TextBox x:Name="txt_Message"
Width="400"></TextBox>
<Button Name="btn_instantMessage"
Content="Send Message"></Button>
<Label Content="Send To All Zones"></Label>
<CheckBox Name="chk_sentMessageToAllZones"
VerticalAlignment="Center"
HorizontalAlignment="Right"></CheckBox>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Left" >
<Button Content="Stop All Ads"
Margin="5"
Name="btn_stop"></Button>
<Button Content="Play All Ads"
Margin="5"
Name="btn_play"></Button>
</StackPanel>
</Grid>
Here is a screen shot of the damage. You can see how the button "Play All Ads" is getting cut off.
You should set SizeToContent property on your window/UC.
SizeToContent="Width"

I'm confused with Grid layout in ListBoxItem of WPF

I'm newer in wpf,recently i have a requirement need to create an listbox and when i practice in DataTemplate ,the issue comed.my layout code like below
<ListBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Left">
<ListBoxItem HorizontalAlignment="Stretch">
<Grid ShowGridLines="True" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.ColumnSpan="2"
Width="200" Height="40" Fill="Gray"/>
</Grid>
</ListBoxItem>
</ListBox>
the begining,i set the width 100 on the first column,because the Rectange's width become to 200,so the first column width become more greater than 100,what happend when the grid to measue the child element?i am confused about it ,because i put the code in an commen state it run normally.any one tell me ,thanks

WPF: getting AccessText in ScrollViewer to wrap

I have a Grid containing a ScrollViewer containing AccessText. I want the AccessText to take up the full width of the ScrollViewer, which should take up the full width of the Grid, without any overflow. Currently, the contents of my AccessText are cut off on the right side of the screen instead of wrapping. I have tried setting AccessText.TextWrapping to Wrap, WrapWithOverflow, and I've also tried removing the property entirely. I switched to using a Grid instead of a StackPanel because I thought that might affect how the contents are sized, but that hasn't helped. Here's what I have:
<Grid MaxHeight="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<AccessText Text="{Binding MyLongTextField}"/>
</ScrollViewer>
</Grid>
When you set ColumnDefinition Width to Auto, the ScrollViewer within it won't be limited by the "visible Width" of the Column, so it will still take up as much horizontal space as it needs. With the xaml you posted, I think Width="*" will suit your needs. For the ScrollViewer, it seems like you don't want it to be able to Scroll horizontaly but only verticaly? In that case, set HorizontalScrollBarVisibility="Disabled". Otherwise you'll get a Horizontal ScrollBar.
<Grid MaxHeight="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<AccessText TextWrapping="Wrap" Text="{Binding MyLongTextField}"/>
</ScrollViewer>
</Grid>
If you simply want the AccessText to wrap indefinitely, modify your second ColumnDefinition from Auto to * and move the AccessText outside of the ScrollViewer as seen below...
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<AccessText Grid.Column="1" TextWrapping="Wrap" Text="{Binding MyLongTextField}"/>
</Grid>
The reason the text would not wrap is because the second ColumnDefinition was set to Auto; which essentially does not force a bounds around the AccessText.
If you want to keep the ScrollViewer try this...
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
<AccessText TextWrapping="Wrap" Text="{Binding MyLongTextField}"/>
</ScrollViewer>
</Grid>
This ended up giving me what I wanted:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" MaxHeight="40"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<AccessText Text="{Binding CRData.Error}" TextWrapping="Wrap"/>
</ScrollViewer>
</Grid>
Thanks to Meleak and Aaron for the suggestion of using * for the column width instead of Auto, and to Meleak for suggesting Disabled for the horizontal scrollbar instead of Auto.

WPF layout for autosize textblock and icon floating on the right - how?

I am trying to get a layout where an icon floats on the right end of a textblock; the textblock grows/shrinks to content. I cannot make this happen without the textblock running outside the grid. For example:
<Grid x:Name="LayoutRoot" Width="500" HorizontalAlignment="Left" ShowGridLines="True" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="0" >
<TextBlock.Text>longer keeps going and going testgrand you going and then t
</TextBlock.Text>
</TextBlock>
<Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="1"/>
</Grid>
Seems like the natural approach and works fine when the text is shorter than the column/grid, except the textbox and column will grow indefinitely and not honor the bounds of the grid.
The inverse, with the icon on the left, works fine with a simpler layout, and the textblock doesn’t grow indefinitely. This is achieved with this markup:
<Grid Grid.Row="1" Width="500" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="0"/>
<TextBlock x:Name="textBlock2" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="1" HorizontalAlignment="Left">
<TextBlock.Text>longer testgrow the textblock and it will just keep growing but it will stop when it gets too </TextBlock.Text>
</TextBlock>
</Grid>
Any help appreciated. If a grid won’t work, is there an alternate layout where I can get the icon floating on the right of the text, and the textblock will trim text when it’s too long?
Also:
No, using * size columns doesn't work because the columns are fixed, and the icon won't float at the end of the text
A DockPanel doesn't work either, or at least I or others I've asked haven't been able to. The best it can do is to have the icon half-cut-off outside the dockpanel's right side.
Can you get what you want by setting MaxWidth on the TextBlock? If you add MaxWidth="460" to your first example:
<Grid x:Name="LayoutRoot" Width="500" HorizontalAlignment="Left" ShowGridLines="True" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock MaxWidth="460" x:Name="textBlock" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="0" >
<TextBlock.Text>longer keeps going and going testgrand you going and then t</TextBlock.Text>
</TextBlock>
<Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="1"/>
</Grid>
Then the TextBlock will grow horizontally and always have the rectangle immediately on its right. It won't be wider than 460, so the TextBlock plus the Rectangle shouldn't be wider than 500. If you need the Grid to resize dynamically then you can bind TextBlock.MaxWidth to Grid.ActualWidth with a converter that subtracts the width of the Rectangle.
Edit:
Actually, it should be even simpler than that. Use star sizing on the columns, but set MaxWidth instead of Width on the Grid. That way, the grid itself will get smaller when the text is smaller so that the rectangle is always at the edge of the text.
<Grid x:Name="LayoutRoot" MaxWidth="500" HorizontalAlignment="Left" ShowGridLines="True" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" VerticalAlignment="Top" Height="25" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" Grid.Column="0" >
<TextBlock.Text>longer keeps going and going testgrand you going and then t</TextBlock.Text>
</TextBlock>
<Rectangle Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" Grid.Column="1"/>
</Grid>
Someone internally suggested this answer, which works:
<WrapPanel HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<AccessText TextTrimming="CharacterEllipsis" Grid.Column="0" Margin="0,0,4,0" Text="type more typingon the long hi longer than what if you keep tyingin and get to the end and that's why it changed because you were in the middle" />
<Border Grid.Column="1" Width="10" Height="10" Background="Red" />
</Grid>
</WrapPanel>
The wrappanel seems to provide the necessary magic. I haven't tried Quartermeister's but will save it for future reference!
Our final layout is more complicated and looks like this (it's the header bar for an expander):
<WrapPanel Orientation="Vertical">
<Grid x:Name="HeaderSite" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19" />
<ColumnDefinition Width="16" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" /> <!-- 7/14: fix from list: wrap the whole thing in a wrappanel. Allows for one * col. -->
<ColumnDefinition Width="19" />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="buttonExpanderToggleButton"
Height="20" VerticalAlignment="Top"
/>
<Image x:Name="imageActivityIcon" Grid.Column="1"
Height="16" Width="16"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="0"/>
<AccessText x:Name="textActivityID"
Grid.Column="2"
VerticalAlignment="Top" Margin="5,2,0,0"
TextTrimming="CharacterEllipsis"
FontSize="12" HorizontalAlignment="Left" Text="MA77777"/>
<AccessText x:Name="textActivityHeader"
Grid.Column="3"
VerticalAlignment="Top" Margin="0,2,0,0"
TextTrimming="CharacterEllipsis"
FontSize="12" HorizontalAlignment="Left" Text="Title title title title aand Title title title title a little and if you type more what happens as you keep typing "/>
<AccessText x:Name="textActivityStatus"
FontWeight="Normal"
FontStyle="Italic"
Grid.Column="4"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Top" Margin="0,2,8,0"
FontSize="12" HorizontalAlignment="Left" Text="(On Hold)"/>
<Image x:Name="imageLink"
Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="5"/>
</Grid>
</WrapPanel>
This works fine too even with the other auto sized columns. The key seems to be the wrappanel and the one * sized column. If you set them all to auto it doesn't work.
I hope this and Quartermeister's answer helps somebody, because this drove me #$%#$% crazy.
The below code will result in the following output, is that what you are looking for???
longer keeps going and going... [red rectangle]
<Grid Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="longer keeps going and going testgrand you going and then t" TextTrimming="CharacterEllipsis"/>
<Rectangle Grid.Column="1" Fill="#FFDE3030" Stroke="Black" VerticalAlignment="Top" Height="41" Width="41" />
</Grid>
I had a somewhat similar problem; I wanted to show some content with an externally-sized border area but containing two TextBlocks, where the first is auto-sized and the second is fixed-sized, and the second floats left as the first gets smaller but stops at the right edge (so the first block's text is clipped instead of the second becoming invisible).
Distilling the previous answers, it appears that the key bit of magic is simply to use HorizontalAlignment="Left" with the first column set to star-sized.
<Border BorderThickness="1" BorderBrush="Black">
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Value}" />
<TextBlock Grid.Column="1" Text="⏫" Margin="4,0,0,0" Foreground="Blue" />
</Grid>
</Border>
It appears that the way this works is that (a bit counter-intuitively) the Border stays full width (as set by its parent layout), while the Grid will size to its content -- except that it will not get wider than the containing Border. This keeps the second TextBlock visible.

Silverlight - Auto-resize textbox to fill up empty space

Ok this is what I wish to do.
I have a resizeable window which has 3 controls in same row in flowing order: textBlock, textBox and button.
textBlock and button have dynamic texts. So theirs size depends upon text inside.
Now what I wish to do is that textBox in the middle is always filling up all empty space between textBlock and button.
How do I do that?
I tried with the following code but it doesn't work because of fixed width in 1. and 3. column.
<Grid Margin="0,0,5,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Left" Text="Text1"/>
<TextBox Grid.Column="1"/>
<Button Grid.Column="2" Content="Button1" HorizontalAlignment="Center"/>
</Grid>
You can use Auto for the two outer column widths instead of specifying the width
<Grid Margin="0,0,5,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Text1" />
<TextBox Grid.Column="1"/>
<Button Grid.Column="2" Content="Button1" />
</Grid>
You probably don't need the HorizontalAlignment in the columns either

Resources