margin on context menu not completely removed when using ItemsPanelTemplate - wpf

i used an itemspaneltemplate to remove the white margin on a context menu, theres a very thin white line left behind that i cant seem to get rid of
i'd like the whole context menu background to be gray so i tried this but theres just a white line left behind
<ContextMenu Background="Gray" BorderBrush="Black" BorderThickness="3">
<ContextMenu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="Gray"/>
</ItemsPanelTemplate>
</ContextMenu.ItemsPanel>
</ContextMenu>
enter image description here

Related

How to make the items in a WPF ListBox wrap horizontally and vertically

I want to show a list of thumbnails, and allow the user to choose one. A ListBox seemed an obvious choice, setting the template to include the thumbnail and description.
The following code does this correctly...
<ListBox Margin="5"
Name="BackgroundsLb">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Margin="5"
BorderBrush="Black"
BorderThickness="1">
<StackPanel Margin="5">
<Image Source="{Binding Path=Data, Converter={StaticResource BytesToImageVC}}"
Width="150"
HorizontalAlignment="Center" />
<TextBlock Text="{Binding Path=Description}"
HorizontalAlignment="Center" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
However, this displays the thumbnails vertically, one per row, as is normal for a ListBox. Given that the thumbnails are only 150 pixels wide, I would like to show them in something more like a grid, but (ideally) in a way so that the number of columns adapts to the size of the window.
I tried replacing the ListBox with an ItemsControl, adding in the following...
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
...and it displayed exactly how I wanted it, but the ItemsControl does not allow selection, so is no use for my purpose.
Is there a way to achieve a flexible, selectable display that fills the horizontal space, and breaks onto a new row according to the size of the window?
Thanks
You can use an ItemsPanelTemplate in a ListBox just the same as you are using one in the ItemsControl. The difference I think you're seeing is that ListBox uses scroll bars by default rather than wrapping the content. Basically the content is allowed to grow forever, so you never get the wrap. Instead you get a scrollbar. The good news is you can disable this behavior. The following should give you a horizontal wrap, where new rows are created as needed.
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

WPF ListView shrink contents to fit container

I have a ListView that displays x items. It's defined like so;
<UserControl>
<UserControl.Resources>
<DataTemplate x:Key="MyCard" DataType="models:MyModel">
<StackPanel Background="{Binding BackgroundColour}"
Orientation="Vertical">
<Image Source="{Binding ImageSource}"
Stretch="Uniform"/>
<Label Content="{Binding MyType, Converter={StaticResource EnumDisplayNameConverter}}" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<ListView ItemsSource="{x:Static myNamespace:MyViewModel.Options}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ItemTemplate="{StaticResource MyCard}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</UserControl>
Unfortunately, the items still flow off the viewable area and get clipped, like so;
I was expecting that the items would resize to fit the bounds, but this is obviously not the case. I've tried adding a ViewBox to the DataTemplate to resolve this but it's still not working as expected.
The images are all 300px x 300px and I've tried setting MaxWidth/MaxHeight on the StackPanel, ViewBox and Image but it still flows off the "end".
Any suggestions on how I can resolve this?
Inside inner template, do not use StackPanel as it's growing bounds automatically to accommodate content (and would overlap ListBox scrollable area as well). If you expect auto-resizing, use Grid instead or set exact sizes on inner controls like Image etc.

Align text vertical and horizontal center in stack panel?

I am trying to align a textblock vertically and horizontally center in a stack panel which is there in Listview but i am only able to get text vetically center but not horizontally. Plus the text is not getting wrapped. Here is the code that i have tried:
<ListBox Name="lstTiles" Margin="12,0,-12,0" Grid.Row="1" SelectionChanged="lstTiles_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="{StaticResource PhoneAccentBrush}" Width="145" Height="80" Margin="8,8,0,0" Orientation="Vertical" >
<TextBlock Text="{Binding Name}" Tag="{Binding ID}" Style="{StaticResource PhoneTextNormalStyle}" FontSize="15" TextWrapping="Wrap" TextAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How can i achieve text vertically, horizontally and textwrap?
It looks like since you have the orientation of the StackPanel set to Horizontal, you're putting textblocks next to each other rather than on top of each other. Since the StackPanel elements take the size of their children, you would be able to visualize this as a horizontal, side-by-side, listing of textblocks. Since each textblock takes the size of the text that is in it, you are going to see blocks that are of varying widths, so centering horizontally is going to have no effect.
You could use margins (a pain) to accomplish equal widths. I don't recommend this.
You could also put grids of a set width in the stack panel, and put the textblocks on the grid. You may be able to set the width of the textblocks to get the right effect, but I can't test this at the moment, and I don't remember if it will cause the text to stretch or not.
For text wrapping, I assume you're talking about within the textblock, and that's easy - just set the textblock's TextWrapping property to Wrap.
Try setting the HorizontalContentAlignment and VerticalContentAlignment properties on the listboxitem. I don't have my dev computer now, so I can't experiment, but here is a post that might help you: Silverlight 3: ListBox DataTemplate HorizontalAlignment. Look at both of the first two answers, and see which one might be most helpful in your situation, substituting center, of course, in place of left, top, or stretch.

VirtualizingStackPanel doesn't clear the text of TextBoxes in the ItemTemplate

I have ItemsControl with VirtualizingStackPanel as items panel like this:
<ItemsControl Style="{StaticResource ItemsControl}" Name="itemsControl"
Margin="0,100,0,0" HorizontalAlignment="Stretch" Height="80">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Style is following:
<Style x:Key="ItemsControl" TargetType="ItemsControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Visible">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I set a collection with 100.000 elements as ItemsSource and get really good performance. Everything is fine except of one thing. When I input text in one of the text boxes and then start to scroll I see that that text appears everywhere throughout the list!
I understand what the VirtualizingStackPanel does. It's continuously loading elements that become visible as we scroll. I understand some aspects of it's virtualizing technique but I have no idea how to understand this strange behavior. I failed to find good doc's on WPF/Silverlight virtualization, so, please, explain me what is going on
VirtualizingStackPanel does not actually continiously load elements. Instead, it re-uses the existing elements (controls) and simply replaces the DataContext behind them.
So if you have an VirtualizingStackPanel with 100,000 items, and only 10 are visible at a time, it usually renders about 14 items (extra items for a scroll buffer). When you scroll, the DataContext behind those 14 controls gets changed, but the actual controls themselves will never get replaced.
If you do something like enter Text in TextBox #1, and that TextBox.Text is not bound to anything, then the Text will always show up because the control is getting re-used. If you bind the TextBox.Text to a value, then the DataContext will change when you scroll which will replace the displayed Text.
Not sure how to turn off recycling directly in a VirtualizingStackPanel but this is the syntax in a ListBox. I would have posted as a comment but I wanted formatted code.
<ListBox VirtualizingStackPanel.VirtualizationMode="Standard" />

Getting UI virtualization working with ItemsControl in Silverlight

I'm trying to create a scrolling list of fairly large textblocks. I want there to be a vertical scrollbar to show them all, and if they overflow a certain size I want them to display an ellipsis. I actually have all this working pretty good.
I have the following Silverlight XAML:
<Grid x:Name="LayoutRoot" MaxWidth="500" MinWidth="100"
MaxHeight="500" MinHeight="100">
<Grid.DataContext>
<app:MainPageViewModel/>
</Grid.DataContext>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding TextItems}" Margin="0,20,0,20">
<ItemsControl.ItemTemplate><DataTemplate>
<Border MaxHeight="175" Margin="0,0,0,18" CornerRadius="5">
<TextBlock Margin="2" TextTrimming="WordEllipsis"
TextWrapping="Wrap" Text="{Binding}"/>
</Border>
</DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
My problem is that this layout does not use UI virtualization, such as with a VirtualizingStackPanel. So it is pretty slow. What is the best way to get UI virtualization into this layout? I've tried about a half dozen different ways and nothing has worked out all that well.
I managed to get this working in a ListBox because it seems to support virtualization out of the box. However, I'd prefer to use ItemsControl as I don't want these things to be selectable, and I don't want the styling that comes along with a ListBox.
This in Silverlight 4.
There are a few things you need to do to make this work.
Set the ItemsPanelTemplate for
your ItemsControl to a
VirtualizingStackPanel.
Incorporate the ScrollViewer inside
a ControlTemplate for your
ItemsControl instead of just
wrapping it around the outside.
Make sure the ItemsControl has a fixed height so the layout system can work out how many items it needs to fill the viewport. (It looks like you are already doing this by putting the ItemsControl in a Grid - that will allow the layout system to determine the alloted height for the control)
Here's the simplest example I could come up with of this working:
<ItemsControl ItemsSource="{Binding TextItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>

Resources